chore: git mod - adding init saga and connecting components to ctx (#38088)
## Description - Adds more selectors - Adds more sagas - Introduces init steps for git - Improvements upon CtxAwareGitQuickActions Fixes #37800 Fixes #36814 ## Automation /ok-to-test tags="@tag.Git" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/12295168481> > Commit: ea1ab497cad677aac36f044462e623e526d421d1 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12295168481&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Thu, 12 Dec 2024 12:06:09 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Introduced a context provider for managing Git-related state. - Added a `GitQuickActions` component for various Git actions. - Implemented custom hooks for managing Git branches, metadata, operations, and settings. - Added Redux Saga functions for fetching Git metadata and protected branches. - Enhanced autocommit functionality with polling for progress. - Introduced actions for managing the autocommit process and fetching protected branches. - Added new actions to initialize Git for editor context and manage loading states. - **Bug Fixes** - Improved error handling in various action creators and sagas. - **Chores** - Updated action creators and types for better type safety and clarity. - Refined test cases for components to ensure accurate button selection. - Modified request functions to utilize Axios promises directly for better consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
8e30a389e4
commit
0808b279fa
|
|
@ -5,9 +5,13 @@ import useStatusChangeCount from "./hooks/useStatusChangeCount";
|
||||||
|
|
||||||
function CtxAwareGitQuickActions() {
|
function CtxAwareGitQuickActions() {
|
||||||
const {
|
const {
|
||||||
|
autocommitEnabled,
|
||||||
|
autocommitPolling,
|
||||||
discard,
|
discard,
|
||||||
discardLoading,
|
discardLoading,
|
||||||
fetchStatusLoading,
|
fetchStatusLoading,
|
||||||
|
gitConnected,
|
||||||
|
protectedMode,
|
||||||
pull,
|
pull,
|
||||||
pullError,
|
pullError,
|
||||||
pullLoading,
|
pullLoading,
|
||||||
|
|
@ -17,12 +21,7 @@ function CtxAwareGitQuickActions() {
|
||||||
toggleGitSettingsModal,
|
toggleGitSettingsModal,
|
||||||
} = useGitContext();
|
} = useGitContext();
|
||||||
|
|
||||||
const isGitConnected = false;
|
const connectPermitted = true;
|
||||||
const isAutocommitEnabled = true;
|
|
||||||
const isAutocommitPolling = false;
|
|
||||||
const isConnectPermitted = true;
|
|
||||||
const isProtectedMode = false;
|
|
||||||
|
|
||||||
const isPullFailing = !!pullError;
|
const isPullFailing = !!pullError;
|
||||||
const isStatusClean = status?.isClean ?? false;
|
const isStatusClean = status?.isClean ?? false;
|
||||||
const statusBehindCount = status?.behindCount ?? 0;
|
const statusBehindCount = status?.behindCount ?? 0;
|
||||||
|
|
@ -31,13 +30,13 @@ function CtxAwareGitQuickActions() {
|
||||||
return (
|
return (
|
||||||
<GitQuickActions
|
<GitQuickActions
|
||||||
discard={discard}
|
discard={discard}
|
||||||
isAutocommitEnabled={isAutocommitEnabled}
|
isAutocommitEnabled={autocommitEnabled}
|
||||||
isAutocommitPolling={isAutocommitPolling}
|
isAutocommitPolling={autocommitPolling}
|
||||||
isConnectPermitted={isConnectPermitted}
|
isConnectPermitted={connectPermitted}
|
||||||
isDiscardLoading={discardLoading}
|
isDiscardLoading={discardLoading}
|
||||||
isFetchStatusLoading={fetchStatusLoading}
|
isFetchStatusLoading={fetchStatusLoading}
|
||||||
isGitConnected={isGitConnected}
|
isGitConnected={gitConnected}
|
||||||
isProtectedMode={isProtectedMode}
|
isProtectedMode={protectedMode}
|
||||||
isPullFailing={isPullFailing}
|
isPullFailing={isPullFailing}
|
||||||
isPullLoading={pullLoading}
|
isPullLoading={pullLoading}
|
||||||
isStatusClean={isStatusClean}
|
isStatusClean={isStatusClean}
|
||||||
|
|
|
||||||
|
|
@ -113,18 +113,18 @@ export default function useGitBranches({
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
branches: branchesState?.value ?? null,
|
branches: branchesState?.value,
|
||||||
fetchBranchesLoading: branchesState?.loading ?? false,
|
fetchBranchesLoading: branchesState?.loading ?? false,
|
||||||
fetchBranchesError: branchesState?.error ?? null,
|
fetchBranchesError: branchesState?.error,
|
||||||
fetchBranches,
|
fetchBranches,
|
||||||
createBranchLoading: createBranchState?.loading ?? false,
|
createBranchLoading: createBranchState?.loading ?? false,
|
||||||
createBranchError: createBranchState?.error ?? null,
|
createBranchError: createBranchState?.error,
|
||||||
createBranch,
|
createBranch,
|
||||||
deleteBranchLoading: deleteBranchState?.loading ?? false,
|
deleteBranchLoading: deleteBranchState?.loading ?? false,
|
||||||
deleteBranchError: deleteBranchState?.error ?? null,
|
deleteBranchError: deleteBranchState?.error,
|
||||||
deleteBranch,
|
deleteBranch,
|
||||||
checkoutBranchLoading: checkoutBranchState?.loading ?? false,
|
checkoutBranchLoading: checkoutBranchState?.loading ?? false,
|
||||||
checkoutBranchError: checkoutBranchState?.error ?? null,
|
checkoutBranchError: checkoutBranchState?.error,
|
||||||
checkoutBranch,
|
checkoutBranch,
|
||||||
toggleGitBranchListPopup,
|
toggleGitBranchListPopup,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import useGitOps from "./useGitOps";
|
||||||
import useGitBranches from "./useGitBranches";
|
import useGitBranches from "./useGitBranches";
|
||||||
import useGitSettings from "./useGitSettings";
|
import useGitSettings from "./useGitSettings";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
import type { UseGitMetadataReturnValue } from "./useGitMetadata";
|
||||||
|
import useGitMetadata from "./useGitMetadata";
|
||||||
|
|
||||||
interface UseGitContextValueParams {
|
interface UseGitContextValueParams {
|
||||||
artifactType: keyof typeof GitArtifactType;
|
artifactType: keyof typeof GitArtifactType;
|
||||||
|
|
@ -15,7 +17,8 @@ interface UseGitContextValueParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GitContextValue
|
export interface GitContextValue
|
||||||
extends UseGitConnectReturnValue,
|
extends UseGitMetadataReturnValue,
|
||||||
|
UseGitConnectReturnValue,
|
||||||
UseGitOpsReturnValue,
|
UseGitOpsReturnValue,
|
||||||
UseGitSettingsReturnValue,
|
UseGitSettingsReturnValue,
|
||||||
UseGitBranchesReturnValue {}
|
UseGitBranchesReturnValue {}
|
||||||
|
|
@ -28,12 +31,14 @@ export default function useGitContextValue({
|
||||||
() => ({ artifactType, baseArtifactId }),
|
() => ({ artifactType, baseArtifactId }),
|
||||||
[artifactType, baseArtifactId],
|
[artifactType, baseArtifactId],
|
||||||
);
|
);
|
||||||
|
const useGitMetadataReturnValue = useGitMetadata(basePayload);
|
||||||
const useGitConnectReturnValue = useGitConnect(basePayload);
|
const useGitConnectReturnValue = useGitConnect(basePayload);
|
||||||
const useGitOpsReturnValue = useGitOps(basePayload);
|
const useGitOpsReturnValue = useGitOps(basePayload);
|
||||||
const useGitBranchesReturnValue = useGitBranches(basePayload);
|
const useGitBranchesReturnValue = useGitBranches(basePayload);
|
||||||
const useGitSettingsReturnValue = useGitSettings(basePayload);
|
const useGitSettingsReturnValue = useGitSettings(basePayload);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
...useGitMetadataReturnValue,
|
||||||
...useGitOpsReturnValue,
|
...useGitOpsReturnValue,
|
||||||
...useGitBranchesReturnValue,
|
...useGitBranchesReturnValue,
|
||||||
...useGitConnectReturnValue,
|
...useGitConnectReturnValue,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import type { GitArtifactType } from "git/constants/enums";
|
||||||
|
import type { FetchGitMetadataResponseData } from "git/requests/fetchGitMetadataRequest.types";
|
||||||
|
import {
|
||||||
|
selectGitConnected,
|
||||||
|
selectGitMetadata,
|
||||||
|
} from "git/store/selectors/gitSingleArtifactSelectors";
|
||||||
|
import type { GitRootState } from "git/store/types";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
interface UseGitMetadataParams {
|
||||||
|
artifactType: keyof typeof GitArtifactType;
|
||||||
|
baseArtifactId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseGitMetadataReturnValue {
|
||||||
|
gitMetadata: FetchGitMetadataResponseData | null;
|
||||||
|
fetchGitMetadataLoading: boolean;
|
||||||
|
fetchGitMetadataError: string | null;
|
||||||
|
gitConnected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function useGitMetadata({
|
||||||
|
artifactType,
|
||||||
|
baseArtifactId,
|
||||||
|
}: UseGitMetadataParams): UseGitMetadataReturnValue {
|
||||||
|
const basePayload = useMemo(
|
||||||
|
() => ({ artifactType, baseArtifactId }),
|
||||||
|
[artifactType, baseArtifactId],
|
||||||
|
);
|
||||||
|
|
||||||
|
const gitMetadataState = useSelector((state: GitRootState) =>
|
||||||
|
selectGitMetadata(state, basePayload),
|
||||||
|
);
|
||||||
|
const gitConnected = useSelector((state: GitRootState) =>
|
||||||
|
selectGitConnected(state, basePayload),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
gitMetadata: gitMetadataState.value,
|
||||||
|
fetchGitMetadataLoading: gitMetadataState.loading ?? false,
|
||||||
|
fetchGitMetadataError: gitMetadataState.error,
|
||||||
|
gitConnected: gitConnected ?? false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -133,24 +133,24 @@ export default function useGitOps({
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commitLoading: commitState?.loading ?? false,
|
commitLoading: commitState?.loading ?? false,
|
||||||
commitError: commitState?.error ?? null,
|
commitError: commitState?.error,
|
||||||
commit,
|
commit,
|
||||||
discardLoading: discardState?.loading ?? false,
|
discardLoading: discardState?.loading ?? false,
|
||||||
discardError: discardState?.error ?? null,
|
discardError: discardState?.error,
|
||||||
discard,
|
discard,
|
||||||
status: statusState?.value ?? null,
|
status: statusState?.value,
|
||||||
fetchStatusLoading: statusState?.loading ?? false,
|
fetchStatusLoading: statusState?.loading ?? false,
|
||||||
fetchStatusError: statusState?.error ?? null,
|
fetchStatusError: statusState?.error,
|
||||||
fetchStatus,
|
fetchStatus,
|
||||||
mergeLoading: mergeState?.loading ?? false,
|
mergeLoading: mergeState?.loading ?? false,
|
||||||
mergeError: mergeState?.error ?? null,
|
mergeError: mergeState?.error,
|
||||||
merge,
|
merge,
|
||||||
mergeStatus: mergeStatusState?.value ?? null,
|
mergeStatus: mergeStatusState?.value,
|
||||||
fetchMergeStatusLoading: mergeStatusState?.loading ?? false,
|
fetchMergeStatusLoading: mergeStatusState?.loading ?? false,
|
||||||
fetchMergeStatusError: mergeStatusState?.error ?? null,
|
fetchMergeStatusError: mergeStatusState?.error,
|
||||||
fetchMergeStatus,
|
fetchMergeStatus,
|
||||||
pullLoading: pullState?.loading ?? false,
|
pullLoading: pullState?.loading ?? false,
|
||||||
pullError: pullState?.error ?? null,
|
pullError: pullState?.error,
|
||||||
pull,
|
pull,
|
||||||
toggleGitOpsModal,
|
toggleGitOpsModal,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
import type { GitArtifactType, GitSettingsTab } from "git/constants/enums";
|
import type { GitArtifactType, GitSettingsTab } from "git/constants/enums";
|
||||||
|
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
|
||||||
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
||||||
|
import {
|
||||||
|
selectAutocommitEnabled,
|
||||||
|
selectAutocommitPolling,
|
||||||
|
selectProtectedBranches,
|
||||||
|
selectProtectedMode,
|
||||||
|
} from "git/store/selectors/gitSingleArtifactSelectors";
|
||||||
|
import type { GitRootState } from "git/store/types";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
interface UseGitSettingsParams {
|
interface UseGitSettingsParams {
|
||||||
artifactType: keyof typeof GitArtifactType;
|
artifactType: keyof typeof GitArtifactType;
|
||||||
|
|
@ -9,6 +17,13 @@ interface UseGitSettingsParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UseGitSettingsReturnValue {
|
export interface UseGitSettingsReturnValue {
|
||||||
|
autocommitEnabled: boolean;
|
||||||
|
autocommitPolling: boolean;
|
||||||
|
protectedBranches: FetchProtectedBranchesResponseData | null;
|
||||||
|
fetchProtectedBranchesLoading: boolean;
|
||||||
|
fetchProtectedBranchesError: string | null;
|
||||||
|
fetchProtectedBranches: () => void;
|
||||||
|
protectedMode: boolean;
|
||||||
toggleGitSettingsModal: (
|
toggleGitSettingsModal: (
|
||||||
open: boolean,
|
open: boolean,
|
||||||
tab: keyof typeof GitSettingsTab,
|
tab: keyof typeof GitSettingsTab,
|
||||||
|
|
@ -25,6 +40,33 @@ export default function useGitSettings({
|
||||||
[artifactType, baseArtifactId],
|
[artifactType, baseArtifactId],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// autocommit
|
||||||
|
const autocommitEnabled = useSelector((state: GitRootState) =>
|
||||||
|
selectAutocommitEnabled(state, basePayload),
|
||||||
|
);
|
||||||
|
|
||||||
|
const autocommitPolling = useSelector((state: GitRootState) =>
|
||||||
|
selectAutocommitPolling(state, basePayload),
|
||||||
|
);
|
||||||
|
|
||||||
|
// branch protection
|
||||||
|
const protectedBranchesState = useSelector((state: GitRootState) =>
|
||||||
|
selectProtectedBranches(state, basePayload),
|
||||||
|
);
|
||||||
|
|
||||||
|
const fetchProtectedBranches = () => {
|
||||||
|
dispatch(
|
||||||
|
gitArtifactActions.fetchProtectedBranchesInit({
|
||||||
|
...basePayload,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const protectedMode = useSelector((state: GitRootState) =>
|
||||||
|
selectProtectedMode(state, basePayload),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ui
|
||||||
const toggleGitSettingsModal = (
|
const toggleGitSettingsModal = (
|
||||||
open: boolean,
|
open: boolean,
|
||||||
tab: keyof typeof GitSettingsTab,
|
tab: keyof typeof GitSettingsTab,
|
||||||
|
|
@ -39,6 +81,13 @@ export default function useGitSettings({
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
autocommitEnabled: autocommitEnabled ?? false,
|
||||||
|
autocommitPolling: autocommitPolling ?? false,
|
||||||
|
protectedBranches: protectedBranchesState.value,
|
||||||
|
fetchProtectedBranchesLoading: protectedBranchesState.loading ?? false,
|
||||||
|
fetchProtectedBranchesError: protectedBranchesState.error,
|
||||||
|
fetchProtectedBranches,
|
||||||
|
protectedMode: protectedMode ?? false,
|
||||||
toggleGitSettingsModal,
|
toggleGitSettingsModal,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { createContext, useContext, useEffect } from "react";
|
import React, { createContext, useContext } from "react";
|
||||||
import type { GitArtifactType } from "git/constants/enums";
|
import type { GitArtifactType } from "git/constants/enums";
|
||||||
import type { GitContextValue } from "./hooks/useGitContextValue";
|
import type { GitContextValue } from "./hooks/useGitContextValue";
|
||||||
import useGitContextValue from "./hooks/useGitContextValue";
|
import useGitContextValue from "./hooks/useGitContextValue";
|
||||||
|
|
@ -15,24 +15,18 @@ interface GitContextProviderProps {
|
||||||
artifactType: keyof typeof GitArtifactType;
|
artifactType: keyof typeof GitArtifactType;
|
||||||
baseArtifactId: string;
|
baseArtifactId: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
// extra
|
||||||
|
// connectPermitted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function GitContextProvider({
|
export default function GitContextProvider({
|
||||||
artifactType,
|
artifactType,
|
||||||
baseArtifactId,
|
baseArtifactId,
|
||||||
children,
|
children,
|
||||||
|
// connectPermitted = true,
|
||||||
}: GitContextProviderProps) {
|
}: GitContextProviderProps) {
|
||||||
const contextValue = useGitContextValue({ artifactType, baseArtifactId });
|
const contextValue = useGitContextValue({ artifactType, baseArtifactId });
|
||||||
|
|
||||||
const { fetchBranches } = contextValue;
|
|
||||||
|
|
||||||
useEffect(
|
|
||||||
function gitInitEffect() {
|
|
||||||
fetchBranches();
|
|
||||||
},
|
|
||||||
[fetchBranches],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GitContext.Provider value={contextValue}>{children}</GitContext.Provider>
|
<GitContext.Provider value={contextValue}>{children}</GitContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ describe("QuickActionButton", () => {
|
||||||
<QuickActionButton {...defaultProps} />
|
<QuickActionButton {...defaultProps} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const btn = container.getElementsByClassName("t--test-btn")[0];
|
const btn = container.querySelectorAll(".t--test-btn button")[0];
|
||||||
|
|
||||||
fireEvent.click(btn);
|
fireEvent.click(btn);
|
||||||
expect(defaultProps.onClick).toHaveBeenCalledTimes(1);
|
expect(defaultProps.onClick).toHaveBeenCalledTimes(1);
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,11 @@ const SpinnerContainer = styled.div`
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const QuickActionButtonContainer = styled.button<{ disabled?: boolean }>`
|
const QuickActionButtonContainer = styled.div<{ disabled?: boolean }>`
|
||||||
margin: 0 ${(props) => props.theme.spaces[1]}px;
|
margin: 0 ${(props) => props.theme.spaces[1]}px;
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
cursor: ${({ disabled = false }) => (disabled ? "not-allowed" : "pointer")};
|
|
||||||
opacity: ${({ disabled = false }) => (disabled ? 0.6 : 1)};
|
opacity: ${({ disabled = false }) => (disabled ? 0.6 : 1)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
@ -57,11 +56,7 @@ function QuickActionButton({
|
||||||
const content = capitalizeFirstLetter(tooltipText);
|
const content = capitalizeFirstLetter(tooltipText);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QuickActionButtonContainer
|
<QuickActionButtonContainer className={className} disabled={disabled}>
|
||||||
className={className}
|
|
||||||
disabled={disabled}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<SpinnerContainer className="t--loader-quick-git-action">
|
<SpinnerContainer className="t--loader-quick-git-action">
|
||||||
<SpinnerLoader size="md" />
|
<SpinnerLoader size="md" />
|
||||||
|
|
@ -73,6 +68,7 @@ function QuickActionButton({
|
||||||
isDisabled={disabled}
|
isDisabled={disabled}
|
||||||
isIconButton
|
isIconButton
|
||||||
kind="tertiary"
|
kind="tertiary"
|
||||||
|
onClick={onClick}
|
||||||
size="md"
|
size="md"
|
||||||
startIcon={icon}
|
startIcon={icon}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,8 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const commitButton = container.getElementsByClassName(
|
const commitButton = container.querySelectorAll(
|
||||||
"t--bottom-bar-commit",
|
".t--bottom-bar-commit button",
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
fireEvent.click(commitButton);
|
fireEvent.click(commitButton);
|
||||||
|
|
@ -145,8 +145,9 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const pullButton =
|
const pullButton = container.querySelectorAll(
|
||||||
container.getElementsByClassName("t--bottom-bar-pull")[0];
|
".t--bottom-bar-pull button",
|
||||||
|
)[0];
|
||||||
|
|
||||||
fireEvent.click(pullButton);
|
fireEvent.click(pullButton);
|
||||||
expect(AnalyticsUtil.logEvent).toHaveBeenCalledWith("GS_PULL_GIT_CLICK", {
|
expect(AnalyticsUtil.logEvent).toHaveBeenCalledWith("GS_PULL_GIT_CLICK", {
|
||||||
|
|
@ -165,8 +166,8 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const mergeButton = container.getElementsByClassName(
|
const mergeButton = container.querySelectorAll(
|
||||||
"t--bottom-bar-merge",
|
".t--bottom-bar-merge button",
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
fireEvent.click(mergeButton);
|
fireEvent.click(mergeButton);
|
||||||
|
|
@ -190,8 +191,8 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const settingsButton = container.getElementsByClassName(
|
const settingsButton = container.querySelectorAll(
|
||||||
"t--bottom-git-settings",
|
".t--bottom-git-settings button",
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
fireEvent.click(settingsButton);
|
fireEvent.click(settingsButton);
|
||||||
|
|
@ -216,8 +217,8 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const commitButton = container.getElementsByClassName(
|
const commitButton = container.querySelectorAll(
|
||||||
"t--bottom-bar-commit",
|
".t--bottom-bar-commit button",
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
expect(commitButton).toBeDisabled();
|
expect(commitButton).toBeDisabled();
|
||||||
|
|
@ -298,8 +299,9 @@ describe("QuickActions Component", () => {
|
||||||
<QuickActions {...props} />
|
<QuickActions {...props} />
|
||||||
</ThemeProvider>,
|
</ThemeProvider>,
|
||||||
);
|
);
|
||||||
const pullButton =
|
const pullButton = container.querySelectorAll(
|
||||||
container.getElementsByClassName("t--bottom-bar-pull")[0];
|
".t--bottom-bar-pull button",
|
||||||
|
)[0];
|
||||||
|
|
||||||
expect(pullButton).toBeDisabled();
|
expect(pullButton).toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ function GitQuickActions({
|
||||||
if (isProtectedMode) {
|
if (isProtectedMode) {
|
||||||
discard();
|
discard();
|
||||||
} else {
|
} else {
|
||||||
|
// ! case: why is triggeredFromBottomBar this needed?
|
||||||
// pull({ triggeredFromBottomBar: true });
|
// pull({ triggeredFromBottomBar: true });
|
||||||
pull();
|
pull();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
CheckoutBranchRequestParams,
|
CheckoutBranchRequestParams,
|
||||||
CheckoutBranchResponse,
|
CheckoutBranchResponse,
|
||||||
|
|
@ -9,7 +9,7 @@ import Api from "api/Api";
|
||||||
export default async function checkoutBranchRequest(
|
export default async function checkoutBranchRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: CheckoutBranchRequestParams,
|
params: CheckoutBranchRequestParams,
|
||||||
): Promise<AxiosResponse<CheckoutBranchResponse>> {
|
): AxiosPromise<CheckoutBranchResponse> {
|
||||||
return Api.get(
|
return Api.get(
|
||||||
`${GIT_BASE_URL}/checkout-branch/app/${branchedApplicationId}`,
|
`${GIT_BASE_URL}/checkout-branch/app/${branchedApplicationId}`,
|
||||||
params,
|
params,
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import type {
|
||||||
CommitResponse,
|
CommitResponse,
|
||||||
} from "./commitRequest.types";
|
} from "./commitRequest.types";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function commitRequest(
|
export default async function commitRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: CommitRequestParams,
|
params: CommitRequestParams,
|
||||||
): Promise<AxiosResponse<CommitResponse>> {
|
): AxiosPromise<CommitResponse> {
|
||||||
return Api.post(
|
return Api.post(
|
||||||
`${GIT_BASE_URL}/commit/app/${branchedApplicationId}`,
|
`${GIT_BASE_URL}/commit/app/${branchedApplicationId}`,
|
||||||
params,
|
params,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
CreateBranchRequestParams,
|
CreateBranchRequestParams,
|
||||||
CreateBranchResponse,
|
CreateBranchResponse,
|
||||||
|
|
@ -9,7 +9,7 @@ import Api from "api/Api";
|
||||||
export default async function createBranchRequest(
|
export default async function createBranchRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: CreateBranchRequestParams,
|
params: CreateBranchRequestParams,
|
||||||
): Promise<AxiosResponse<CreateBranchResponse>> {
|
): AxiosPromise<CreateBranchResponse> {
|
||||||
return Api.post(
|
return Api.post(
|
||||||
`${GIT_BASE_URL}/create-branch/app/${branchedApplicationId}`,
|
`${GIT_BASE_URL}/create-branch/app/${branchedApplicationId}`,
|
||||||
params,
|
params,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
DeleteBranchRequestParams,
|
DeleteBranchRequestParams,
|
||||||
DeleteBranchResponse,
|
DeleteBranchResponse,
|
||||||
|
|
@ -9,6 +9,6 @@ import Api from "api/Api";
|
||||||
export default async function deleteBranchRequest(
|
export default async function deleteBranchRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
params: DeleteBranchRequestParams,
|
params: DeleteBranchRequestParams,
|
||||||
): Promise<AxiosResponse<DeleteBranchResponse>> {
|
): AxiosPromise<DeleteBranchResponse> {
|
||||||
return Api.delete(`${GIT_BASE_URL}/branch/app/${baseApplicationId}`, params);
|
return Api.delete(`${GIT_BASE_URL}/branch/app/${baseApplicationId}`, params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function discardRequest(
|
export default async function discardRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
): Promise<AxiosResponse<void>> {
|
): AxiosPromise<void> {
|
||||||
return Api.put(`${GIT_BASE_URL}/discard/app/${branchedApplicationId}`);
|
return Api.put(`${GIT_BASE_URL}/discard/app/${branchedApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { DisconnectResponse } from "./disconnectRequest.types";
|
import type { DisconnectResponse } from "./disconnectRequest.types";
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
|
|
||||||
export default async function disconnectRequest(
|
export default async function disconnectRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<DisconnectResponse>> {
|
): AxiosPromise<DisconnectResponse> {
|
||||||
return Api.post(`${GIT_BASE_URL}/disconnect/app/${baseApplicationId}`);
|
return Api.post(`${GIT_BASE_URL}/disconnect/app/${baseApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { FetchAutocommitProgressResponse } from "./fetchAutocommitProgressRequest.types";
|
import type { FetchAutocommitProgressResponse } from "./fetchAutocommitProgressRequest.types";
|
||||||
|
|
||||||
export default async function fetchAutocommitProgressRequest(
|
export default async function fetchAutocommitProgressRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<FetchAutocommitProgressResponse>> {
|
): AxiosPromise<FetchAutocommitProgressResponse> {
|
||||||
return Api.get(
|
return Api.get(
|
||||||
`${GIT_BASE_URL}/auto-commit/progress/app/${baseApplicationId}`,
|
`${GIT_BASE_URL}/auto-commit/progress/app/${baseApplicationId}`,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
|
import type { ApiResponse } from "api/types";
|
||||||
import type { AutocommitStatus } from "../constants/enums";
|
import type { AutocommitStatus } from "../constants/enums";
|
||||||
|
|
||||||
export interface FetchAutocommitProgressResponse {
|
export interface FetchAutocommitProgressResponseData {
|
||||||
autoCommitResponse: AutocommitStatus;
|
autoCommitResponse: AutocommitStatus;
|
||||||
progress: number;
|
progress: number;
|
||||||
branchName: string;
|
branchName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type FetchAutocommitProgressResponse =
|
||||||
|
ApiResponse<FetchAutocommitProgressResponseData>;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function fetchBranchesRequest(
|
export default async function fetchBranchesRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: FetchBranchesRequestParams,
|
params: FetchBranchesRequestParams = { pruneBranches: true },
|
||||||
): AxiosPromise<FetchBranchesResponse> {
|
): AxiosPromise<FetchBranchesResponse> {
|
||||||
const queryParams = {} as FetchBranchesRequestParams;
|
const queryParams = {} as FetchBranchesRequestParams;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { ApiResponse } from "api/ApiResponses";
|
import type { ApiResponse } from "api/ApiResponses";
|
||||||
|
|
||||||
export interface FetchBranchesRequestParams {
|
export interface FetchBranchesRequestParams {
|
||||||
pruneBranches: boolean;
|
pruneBranches?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SingleBranch {
|
interface SingleBranch {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { FetchGitMetadataResponse } from "./fetchGitMetadataRequest.types";
|
import type { FetchGitMetadataResponse } from "./fetchGitMetadataRequest.types";
|
||||||
|
|
||||||
export default async function fetchGitMetadataRequest(
|
export default async function fetchGitMetadataRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<FetchGitMetadataResponse>> {
|
): AxiosPromise<FetchGitMetadataResponse> {
|
||||||
return Api.get(`${GIT_BASE_URL}/metadata/app/${baseApplicationId}`);
|
return Api.get(`${GIT_BASE_URL}/metadata/app/${baseApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
export interface FetchGitMetadataResponse {
|
import type { ApiResponse } from "api/types";
|
||||||
|
|
||||||
|
export interface FetchGitMetadataResponseData {
|
||||||
branchName: string;
|
branchName: string;
|
||||||
defaultBranchName: string;
|
defaultBranchName: string;
|
||||||
remoteUrl: string;
|
remoteUrl: string;
|
||||||
|
|
@ -13,3 +15,6 @@ export interface FetchGitMetadataResponse {
|
||||||
};
|
};
|
||||||
isAutoDeploymentEnabled?: boolean;
|
isAutoDeploymentEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type FetchGitMetadataResponse =
|
||||||
|
ApiResponse<FetchGitMetadataResponseData>;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
FetchMergeStatusRequestParams,
|
FetchMergeStatusRequestParams,
|
||||||
FetchMergeStatusResponse,
|
FetchMergeStatusResponse,
|
||||||
|
|
@ -9,7 +9,7 @@ import { GIT_BASE_URL } from "./constants";
|
||||||
export default async function fetchMergeStatusRequest(
|
export default async function fetchMergeStatusRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: FetchMergeStatusRequestParams,
|
params: FetchMergeStatusRequestParams,
|
||||||
): Promise<AxiosResponse<FetchMergeStatusResponse>> {
|
): AxiosPromise<FetchMergeStatusResponse> {
|
||||||
return Api.post(
|
return Api.post(
|
||||||
`${GIT_BASE_URL}/merge/status/app/${branchedApplicationId}`,
|
`${GIT_BASE_URL}/merge/status/app/${branchedApplicationId}`,
|
||||||
params,
|
params,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { FetchProtectedBranches } from "./fetchProtectedBranchesRequest.types";
|
import type { FetchProtectedBranchesResponse } from "./fetchProtectedBranchesRequest.types";
|
||||||
|
|
||||||
export default async function fetchProtectedBranchesRequest(
|
export default async function fetchProtectedBranchesRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<FetchProtectedBranches>> {
|
): AxiosPromise<FetchProtectedBranchesResponse> {
|
||||||
return Api.get(`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`);
|
return Api.get(`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,6 @@
|
||||||
export type FetchProtectedBranches = string[];
|
import type { ApiResponse } from "api/types";
|
||||||
|
|
||||||
|
export type FetchProtectedBranchesResponseData = string[];
|
||||||
|
|
||||||
|
export type FetchProtectedBranchesResponse =
|
||||||
|
ApiResponse<FetchProtectedBranchesResponseData>;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { FetchSSHKeyResponse } from "./fetchSSHKeyRequest.types";
|
import type { FetchSSHKeyResponse } from "./fetchSSHKeyRequest.types";
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { APPLICATION_BASE_URL } from "./constants";
|
import { APPLICATION_BASE_URL } from "./constants";
|
||||||
|
|
||||||
export default async function fetchSSHKeyRequest(
|
export default async function fetchSSHKeyRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<FetchSSHKeyResponse>> {
|
): AxiosPromise<FetchSSHKeyResponse> {
|
||||||
return Api.get(`${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}`);
|
return Api.get(`${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import type {
|
||||||
FetchStatusResponse,
|
FetchStatusResponse,
|
||||||
} from "./fetchStatusRequest.types";
|
} from "./fetchStatusRequest.types";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function fetchStatusRequest(
|
export default async function fetchStatusRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: FetchStatusRequestParams,
|
params: FetchStatusRequestParams = { compareRemote: true },
|
||||||
): Promise<AxiosResponse<FetchStatusResponse>> {
|
): AxiosPromise<FetchStatusResponse> {
|
||||||
return Api.get(`${GIT_BASE_URL}/status/app/${branchedApplicationId}`, params);
|
return Api.get(`${GIT_BASE_URL}/status/app/${branchedApplicationId}`, params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { ApiResponse } from "api/types";
|
import type { ApiResponse } from "api/types";
|
||||||
|
|
||||||
export interface FetchStatusRequestParams {
|
export interface FetchStatusRequestParams {
|
||||||
compareRemote: boolean;
|
compareRemote?: boolean;
|
||||||
}
|
}
|
||||||
export interface FetchStatusResponseData {
|
export interface FetchStatusResponseData {
|
||||||
added: string[];
|
added: string[];
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
GenerateSSHKeyRequestParams,
|
GenerateSSHKeyRequestParams,
|
||||||
GenerateSSHKeyResponse,
|
GenerateSSHKeyResponse,
|
||||||
|
|
@ -9,7 +9,7 @@ import Api from "api/Api";
|
||||||
export default async function generateSSHKeyRequest(
|
export default async function generateSSHKeyRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
params: GenerateSSHKeyRequestParams,
|
params: GenerateSSHKeyRequestParams,
|
||||||
): Promise<AxiosResponse<GenerateSSHKeyResponse>> {
|
): AxiosPromise<GenerateSSHKeyResponse> {
|
||||||
const url = params.isImporting
|
const url = params.isImporting
|
||||||
? `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`
|
? `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`
|
||||||
: `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`;
|
: `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`;
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import type {
|
||||||
ImportGitRequestParams,
|
ImportGitRequestParams,
|
||||||
ImportGitResponse,
|
ImportGitResponse,
|
||||||
} from "./importGitRequest.types";
|
} from "./importGitRequest.types";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function importGitRequest(
|
export default async function importGitRequest(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
params: ImportGitRequestParams,
|
params: ImportGitRequestParams,
|
||||||
): Promise<AxiosResponse<ImportGitResponse>> {
|
): AxiosPromise<ImportGitResponse> {
|
||||||
return Api.post(`${GIT_BASE_URL}/import/${workspaceId}`, params);
|
return Api.post(`${GIT_BASE_URL}/import/${workspaceId}`, params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import type { MergeRequestParams, MergeResponse } from "./mergeRequest.types";
|
import type { MergeRequestParams, MergeResponse } from "./mergeRequest.types";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function mergeRequest(
|
export default async function mergeRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
params: MergeRequestParams,
|
params: MergeRequestParams,
|
||||||
): Promise<AxiosResponse<MergeResponse>> {
|
): AxiosPromise<MergeResponse> {
|
||||||
return Api.post(`${GIT_BASE_URL}/merge/app/${branchedApplicationId}`, params);
|
return Api.post(`${GIT_BASE_URL}/merge/app/${branchedApplicationId}`, params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { PullRequestResponse } from "./pullRequest.types";
|
import type { PullRequestResponse } from "./pullRequest.types";
|
||||||
|
|
||||||
export default async function pullRequest(
|
export default async function pullRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
): Promise<AxiosResponse<PullRequestResponse>> {
|
): AxiosPromise<PullRequestResponse> {
|
||||||
return Api.get(`${GIT_BASE_URL}/pull/app/${branchedApplicationId}`);
|
return Api.get(`${GIT_BASE_URL}/pull/app/${branchedApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { ToggleAutocommitResponse } from "./toggleAutocommitRequest.types";
|
import type { ToggleAutocommitResponse } from "./toggleAutocommitRequest.types";
|
||||||
|
|
||||||
export default async function toggleAutocommitRequest(
|
export default async function toggleAutocommitRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
): Promise<AxiosResponse<ToggleAutocommitResponse>> {
|
): AxiosPromise<ToggleAutocommitResponse> {
|
||||||
return Api.patch(
|
return Api.patch(
|
||||||
`${GIT_BASE_URL}/auto-commit/toggle/app/${baseApplicationId}`,
|
`${GIT_BASE_URL}/auto-commit/toggle/app/${baseApplicationId}`,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import Api from "api/Api";
|
import Api from "api/Api";
|
||||||
import { GIT_BASE_URL } from "./constants";
|
import { GIT_BASE_URL } from "./constants";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type { TriggerAutocommitResponse } from "./triggerAutocommitRequest.types";
|
import type { TriggerAutocommitResponse } from "./triggerAutocommitRequest.types";
|
||||||
|
|
||||||
export default async function triggerAutocommitRequest(
|
export default async function triggerAutocommitRequest(
|
||||||
branchedApplicationId: string,
|
branchedApplicationId: string,
|
||||||
): Promise<AxiosResponse<TriggerAutocommitResponse>> {
|
): AxiosPromise<TriggerAutocommitResponse> {
|
||||||
return Api.post(`${GIT_BASE_URL}/auto-commit/app/${branchedApplicationId}`);
|
return Api.post(`${GIT_BASE_URL}/auto-commit/app/${branchedApplicationId}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
|
import type { ApiResponse } from "api/types";
|
||||||
import type { AutocommitStatus } from "../constants/enums";
|
import type { AutocommitStatus } from "../constants/enums";
|
||||||
|
|
||||||
export interface TriggerAutocommitResponse {
|
export interface TriggerAutocommitResponseData {
|
||||||
autoCommitResponse: AutocommitStatus;
|
autoCommitResponse: AutocommitStatus;
|
||||||
progress: number;
|
progress: number;
|
||||||
branchName: string;
|
branchName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TriggerAutocommitResponse =
|
||||||
|
ApiResponse<TriggerAutocommitResponseData>;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
import type {
|
import type {
|
||||||
UpdateGlobalProfileRequestParams,
|
UpdateGlobalProfileRequestParams,
|
||||||
UpdateGlobalProfileResponse,
|
UpdateGlobalProfileResponse,
|
||||||
|
|
@ -8,6 +8,6 @@ import { GIT_BASE_URL } from "./constants";
|
||||||
|
|
||||||
export default async function updateGlobalProfileRequest(
|
export default async function updateGlobalProfileRequest(
|
||||||
params: UpdateGlobalProfileRequestParams,
|
params: UpdateGlobalProfileRequestParams,
|
||||||
): Promise<AxiosResponse<UpdateGlobalProfileResponse>> {
|
): AxiosPromise<UpdateGlobalProfileResponse> {
|
||||||
return Api.post(`${GIT_BASE_URL}/profile/default`, params);
|
return Api.post(`${GIT_BASE_URL}/profile/default`, params);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import type {
|
||||||
UpdateProtectedBranchesRequestParams,
|
UpdateProtectedBranchesRequestParams,
|
||||||
UpdateProtectedBranchesResponse,
|
UpdateProtectedBranchesResponse,
|
||||||
} from "./updateProtectedBranchesRequest.types";
|
} from "./updateProtectedBranchesRequest.types";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosPromise } from "axios";
|
||||||
|
|
||||||
export default async function updateProtectedBranchesRequest(
|
export default async function updateProtectedBranchesRequest(
|
||||||
baseApplicationId: string,
|
baseApplicationId: string,
|
||||||
params: UpdateProtectedBranchesRequestParams,
|
params: UpdateProtectedBranchesRequestParams,
|
||||||
): Promise<AxiosResponse<UpdateProtectedBranchesResponse>> {
|
): AxiosPromise<UpdateProtectedBranchesResponse> {
|
||||||
return Api.post(
|
return Api.post(
|
||||||
`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`,
|
`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`,
|
||||||
params,
|
params,
|
||||||
|
|
|
||||||
35
app/client/src/git/sagas/fetchGitMetadataSaga.ts
Normal file
35
app/client/src/git/sagas/fetchGitMetadataSaga.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import fetchGitMetadataRequest from "git/requests/fetchGitMetadataRequest";
|
||||||
|
import type { FetchGitMetadataResponse } from "git/requests/fetchGitMetadataRequest.types";
|
||||||
|
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
||||||
|
import type { GitArtifactPayloadAction } from "git/store/types";
|
||||||
|
import { call, put } from "redux-saga/effects";
|
||||||
|
import { validateResponse } from "sagas/ErrorSagas";
|
||||||
|
|
||||||
|
export default function* fetchGitMetadataSaga(
|
||||||
|
action: GitArtifactPayloadAction,
|
||||||
|
) {
|
||||||
|
const { artifactType, baseArtifactId } = action.payload;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
let response: FetchGitMetadataResponse | undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = yield call(fetchGitMetadataRequest, baseArtifactId);
|
||||||
|
const isValidResponse: boolean = yield validateResponse(response, false);
|
||||||
|
|
||||||
|
if (response && isValidResponse) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchGitMetadataSuccess({
|
||||||
|
...basePayload,
|
||||||
|
responseData: response.data,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchGitMetadataError({
|
||||||
|
...basePayload,
|
||||||
|
error: error as string,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
app/client/src/git/sagas/fetchProtectedBranchesSaga.ts
Normal file
36
app/client/src/git/sagas/fetchProtectedBranchesSaga.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import fetchProtectedBranchesRequest from "git/requests/fetchProtectedBranchesRequest";
|
||||||
|
import type { FetchProtectedBranchesResponse } from "git/requests/fetchProtectedBranchesRequest.types";
|
||||||
|
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
||||||
|
import type { GitArtifactPayloadAction } from "git/store/types";
|
||||||
|
import { call, put } from "redux-saga/effects";
|
||||||
|
import { validateResponse } from "sagas/ErrorSagas";
|
||||||
|
|
||||||
|
export default function* fetchProtectedBranchesSaga(
|
||||||
|
action: GitArtifactPayloadAction,
|
||||||
|
) {
|
||||||
|
const { artifactType, baseArtifactId } = action.payload;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
let response: FetchProtectedBranchesResponse | undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = yield call(fetchProtectedBranchesRequest, baseArtifactId);
|
||||||
|
|
||||||
|
const isValidResponse: boolean = yield validateResponse(response);
|
||||||
|
|
||||||
|
if (response && isValidResponse) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchProtectedBranchesSuccess({
|
||||||
|
...basePayload,
|
||||||
|
responseData: response.data,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchProtectedBranchesError({
|
||||||
|
...basePayload,
|
||||||
|
error: error as string,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
43
app/client/src/git/sagas/fetchStatusSaga.ts
Normal file
43
app/client/src/git/sagas/fetchStatusSaga.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import fetchStatusRequest from "git/requests/fetchStatusRequest";
|
||||||
|
import type { FetchStatusResponse } from "git/requests/fetchStatusRequest.types";
|
||||||
|
import type { FetchStatusInitPayload } from "git/store/actions/fetchStatusActions";
|
||||||
|
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
||||||
|
import type { GitArtifactPayloadAction } from "git/store/types";
|
||||||
|
import { call, put } from "redux-saga/effects";
|
||||||
|
import { validateResponse } from "sagas/ErrorSagas";
|
||||||
|
|
||||||
|
export default function* fetchStatusSaga(
|
||||||
|
action: GitArtifactPayloadAction<FetchStatusInitPayload>,
|
||||||
|
) {
|
||||||
|
const { artifactType, baseArtifactId } = action.payload;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
let response: FetchStatusResponse | undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = yield call(fetchStatusRequest, baseArtifactId);
|
||||||
|
const isValidResponse: boolean = yield validateResponse(response);
|
||||||
|
|
||||||
|
if (response && isValidResponse) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchStatusSuccess({
|
||||||
|
...basePayload,
|
||||||
|
responseData: response.data,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchStatusError({
|
||||||
|
...basePayload,
|
||||||
|
error: error as string,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// ! case: BETTER ERROR HANDLING
|
||||||
|
// if ((error as Error)?.message?.includes("Auth fail")) {
|
||||||
|
// payload.error = new Error(createMessage(ERROR_GIT_AUTH_FAIL));
|
||||||
|
// } else if ((error as Error)?.message?.includes("Invalid remote: origin")) {
|
||||||
|
// payload.error = new Error(createMessage(ERROR_GIT_INVALID_REMOTE));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,37 +1,99 @@
|
||||||
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
import {
|
||||||
import { all, takeLatest } from "redux-saga/effects";
|
actionChannel,
|
||||||
|
call,
|
||||||
|
fork,
|
||||||
|
take,
|
||||||
|
takeLatest,
|
||||||
|
} from "redux-saga/effects";
|
||||||
|
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 connectSaga from "./connectSaga";
|
||||||
import commitSaga from "./commitSaga";
|
import commitSaga from "./commitSaga";
|
||||||
import { gitConfigActions } from "git/store/gitConfigSlice";
|
|
||||||
import fetchGlobalProfileSaga from "./fetchGlobalProfileSaga";
|
import fetchGlobalProfileSaga from "./fetchGlobalProfileSaga";
|
||||||
import fetchBranchesSaga from "./fetchBranchesSaga";
|
import fetchBranchesSaga from "./fetchBranchesSaga";
|
||||||
import fetchLocalProfileSaga from "./fetchLocalProfileSaga";
|
import fetchLocalProfileSaga from "./fetchLocalProfileSaga";
|
||||||
import updateLocalProfileSaga from "./updateLocalProfileSaga";
|
import updateLocalProfileSaga from "./updateLocalProfileSaga";
|
||||||
import updateGlobalProfileSaga from "./updateGlobalProfileSaga";
|
import updateGlobalProfileSaga from "./updateGlobalProfileSaga";
|
||||||
|
import initGitForEditorSaga from "./initGitSaga";
|
||||||
|
import fetchGitMetadataSaga from "./fetchGitMetadataSaga";
|
||||||
|
import triggerAutocommitSaga from "./triggerAutocommitSaga";
|
||||||
|
import fetchStatusSaga from "./fetchStatusSaga";
|
||||||
|
import fetchProtectedBranchesSaga from "./fetchProtectedBranchesSaga";
|
||||||
|
|
||||||
export function* gitSagas() {
|
const gitRequestBlockingActions: Record<
|
||||||
yield all([
|
string,
|
||||||
takeLatest(gitArtifactActions.connectInit.type, connectSaga),
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(action: PayloadAction<any>) => Generator<any>
|
||||||
|
> = {
|
||||||
|
// init
|
||||||
|
[gitArtifactActions.fetchGitMetadataInit.type]: fetchGitMetadataSaga,
|
||||||
|
|
||||||
// branches
|
// connect
|
||||||
takeLatest(gitArtifactActions.fetchBranchesInit.type, fetchBranchesSaga),
|
[gitArtifactActions.connectInit.type]: connectSaga,
|
||||||
|
|
||||||
takeLatest(gitArtifactActions.commitInit.type, commitSaga),
|
// ops
|
||||||
takeLatest(
|
[gitArtifactActions.commitInit.type]: commitSaga,
|
||||||
gitArtifactActions.fetchLocalProfileInit.type,
|
[gitArtifactActions.fetchStatusInit.type]: fetchStatusSaga,
|
||||||
fetchLocalProfileSaga,
|
|
||||||
),
|
// branches
|
||||||
takeLatest(
|
[gitArtifactActions.fetchBranchesInit.type]: fetchBranchesSaga,
|
||||||
gitArtifactActions.updateLocalProfileInit.type,
|
|
||||||
updateLocalProfileSaga,
|
// settings
|
||||||
),
|
[gitArtifactActions.fetchLocalProfileInit.type]: fetchLocalProfileSaga,
|
||||||
takeLatest(
|
[gitArtifactActions.updateLocalProfileInit.type]: updateLocalProfileSaga,
|
||||||
gitConfigActions.fetchGlobalProfileInit.type,
|
[gitConfigActions.fetchGlobalProfileInit.type]: fetchGlobalProfileSaga,
|
||||||
fetchGlobalProfileSaga,
|
[gitConfigActions.updateGlobalProfileInit.type]: updateGlobalProfileSaga,
|
||||||
),
|
|
||||||
takeLatest(
|
// autocommit
|
||||||
gitConfigActions.updateGlobalProfileInit.type,
|
[gitArtifactActions.triggerAutocommitInit.type]: triggerAutocommitSaga,
|
||||||
updateGlobalProfileSaga,
|
};
|
||||||
),
|
|
||||||
]);
|
const gitRequestNonBlockingActions: Record<
|
||||||
|
string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(action: PayloadAction<any>) => Generator<any>
|
||||||
|
> = {
|
||||||
|
// init
|
||||||
|
[gitArtifactActions.initGitForEditor.type]: initGitForEditorSaga,
|
||||||
|
|
||||||
|
// settings
|
||||||
|
[gitArtifactActions.fetchProtectedBranchesInit.type]:
|
||||||
|
fetchProtectedBranchesSaga,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All git actions on the server are behind a lock,
|
||||||
|
* that means that only one action can be performed at once.
|
||||||
|
*
|
||||||
|
* To follow the same principle, we will queue all actions from the client
|
||||||
|
* as well and only perform one action at a time.
|
||||||
|
*
|
||||||
|
* This will ensure that client is not running parallel requests to the server for git
|
||||||
|
* */
|
||||||
|
function* watchGitBlockingRequests() {
|
||||||
|
const gitActionChannel: TakeableChannel<unknown> = yield actionChannel(
|
||||||
|
objectKeys(gitRequestBlockingActions),
|
||||||
|
);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const action: PayloadAction<unknown> = yield take(gitActionChannel);
|
||||||
|
|
||||||
|
yield call(gitRequestBlockingActions[action.type], action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function* watchGitNonBlockingRequests() {
|
||||||
|
const keys = objectKeys(gitRequestNonBlockingActions);
|
||||||
|
|
||||||
|
for (const actionType of keys) {
|
||||||
|
yield takeLatest(actionType, gitRequestNonBlockingActions[actionType]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* gitSagas() {
|
||||||
|
yield fork(watchGitNonBlockingRequests);
|
||||||
|
yield fork(watchGitBlockingRequests);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
app/client/src/git/sagas/initGitSaga.ts
Normal file
30
app/client/src/git/sagas/initGitSaga.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { GitArtifactType } from "git/constants/enums";
|
||||||
|
import type { InitGitForEditorPayload } from "git/store/actions/initGitActions";
|
||||||
|
import { gitArtifactActions } from "git/store/gitArtifactSlice";
|
||||||
|
import type { GitArtifactPayloadAction } from "git/store/types";
|
||||||
|
import { put, take } from "redux-saga/effects";
|
||||||
|
|
||||||
|
export default function* initGitForEditorSaga(
|
||||||
|
action: GitArtifactPayloadAction<InitGitForEditorPayload>,
|
||||||
|
) {
|
||||||
|
const { artifact, artifactType, baseArtifactId } = action.payload;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
|
||||||
|
yield put(gitArtifactActions.mount(basePayload));
|
||||||
|
|
||||||
|
if (artifactType === GitArtifactType.Application) {
|
||||||
|
if (!!artifact.gitApplicationMetadata) {
|
||||||
|
yield put(gitArtifactActions.fetchGitMetadataInit(basePayload));
|
||||||
|
yield take(gitArtifactActions.fetchGitMetadataSuccess.type);
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.triggerAutocommitInit({
|
||||||
|
...basePayload,
|
||||||
|
artifactId: artifact.id,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
yield put(gitArtifactActions.fetchBranchesInit(basePayload));
|
||||||
|
yield put(gitArtifactActions.fetchProtectedBranchesInit(basePayload));
|
||||||
|
yield put(gitArtifactActions.fetchStatusInit(basePayload));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
131
app/client/src/git/sagas/triggerAutocommitSaga.ts
Normal file
131
app/client/src/git/sagas/triggerAutocommitSaga.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
import { triggerAutocommitSuccessAction } from "actions/gitSyncActions";
|
||||||
|
import { AutocommitStatus, type GitArtifactType } from "git/constants/enums";
|
||||||
|
import fetchAutocommitProgressRequest from "git/requests/fetchAutocommitProgressRequest";
|
||||||
|
import type {
|
||||||
|
FetchAutocommitProgressResponse,
|
||||||
|
FetchAutocommitProgressResponseData,
|
||||||
|
} from "git/requests/fetchAutocommitProgressRequest.types";
|
||||||
|
import triggerAutocommitRequest from "git/requests/triggerAutocommitRequest";
|
||||||
|
import type {
|
||||||
|
TriggerAutocommitResponse,
|
||||||
|
TriggerAutocommitResponseData,
|
||||||
|
} 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 {
|
||||||
|
call,
|
||||||
|
cancel,
|
||||||
|
delay,
|
||||||
|
fork,
|
||||||
|
put,
|
||||||
|
select,
|
||||||
|
take,
|
||||||
|
} from "redux-saga/effects";
|
||||||
|
import type { Task } from "redux-saga";
|
||||||
|
import { validateResponse } from "sagas/ErrorSagas";
|
||||||
|
|
||||||
|
const AUTOCOMMIT_POLL_DELAY = 1000;
|
||||||
|
const AUTOCOMMIT_WHITELISTED_STATES = [
|
||||||
|
AutocommitStatus.PUBLISHED,
|
||||||
|
AutocommitStatus.IN_PROGRESS,
|
||||||
|
AutocommitStatus.LOCKED,
|
||||||
|
];
|
||||||
|
|
||||||
|
interface PollAutocommitProgressParams {
|
||||||
|
artifactType: keyof typeof GitArtifactType;
|
||||||
|
baseArtifactId: string;
|
||||||
|
artifactId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAutocommitHappening(
|
||||||
|
responseData:
|
||||||
|
| TriggerAutocommitResponseData
|
||||||
|
| FetchAutocommitProgressResponseData
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return (
|
||||||
|
!!responseData &&
|
||||||
|
AUTOCOMMIT_WHITELISTED_STATES.includes(responseData.autoCommitResponse)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) {
|
||||||
|
const { artifactId, artifactType, baseArtifactId } = params;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
let triggerResponse: TriggerAutocommitResponse | undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
triggerResponse = yield call(triggerAutocommitRequest, artifactId);
|
||||||
|
const isValidResponse: boolean = yield validateResponse(triggerResponse);
|
||||||
|
|
||||||
|
if (triggerResponse && isValidResponse) {
|
||||||
|
yield put(gitArtifactActions.triggerAutocommitSuccess(basePayload));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.triggerAutocommitError({
|
||||||
|
...basePayload,
|
||||||
|
error: error as string,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isAutocommitHappening(triggerResponse?.data)) {
|
||||||
|
yield put(gitArtifactActions.pollAutocommitProgressStart(basePayload));
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
yield put(gitArtifactActions.fetchAutocommitProgressInit(basePayload));
|
||||||
|
const progressResponse: FetchAutocommitProgressResponse = yield call(
|
||||||
|
fetchAutocommitProgressRequest,
|
||||||
|
baseArtifactId,
|
||||||
|
);
|
||||||
|
const isValidResponse: boolean =
|
||||||
|
yield validateResponse(progressResponse);
|
||||||
|
|
||||||
|
if (isValidResponse && !isAutocommitHappening(progressResponse?.data)) {
|
||||||
|
yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isValidResponse) {
|
||||||
|
yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload));
|
||||||
|
}
|
||||||
|
|
||||||
|
yield delay(AUTOCOMMIT_POLL_DELAY);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload));
|
||||||
|
yield put(
|
||||||
|
gitArtifactActions.fetchAutocommitProgressError({
|
||||||
|
...basePayload,
|
||||||
|
error: error as string,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* triggerAutocommitSaga(
|
||||||
|
action: GitArtifactPayloadAction<TriggerAutocommitInitPayload>,
|
||||||
|
) {
|
||||||
|
const { artifactId, artifactType, baseArtifactId } = action.payload;
|
||||||
|
const basePayload = { artifactType, baseArtifactId };
|
||||||
|
const isAutocommitEnabled: boolean = yield select(
|
||||||
|
selectAutocommitEnabled,
|
||||||
|
basePayload,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isAutocommitEnabled) {
|
||||||
|
const params = { artifactType, baseArtifactId, artifactId };
|
||||||
|
const pollTask: Task = yield fork(pollAutocommitProgressSaga, params);
|
||||||
|
|
||||||
|
yield take(gitArtifactActions.pollAutocommitProgressStop.type);
|
||||||
|
yield cancel(pollTask);
|
||||||
|
} else {
|
||||||
|
yield put(triggerAutocommitSuccessAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
import type {
|
import type { GitAsyncErrorPayload } from "../types";
|
||||||
GitArtifactPayloadAction,
|
|
||||||
GitArtifactErrorPayloadAction,
|
|
||||||
GitAutocommitProgress,
|
|
||||||
} from "../types";
|
|
||||||
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
||||||
|
|
||||||
export const fetchAutocommitProgressInitAction = createSingleArtifactAction(
|
export const fetchAutocommitProgressInitAction = createSingleArtifactAction(
|
||||||
|
|
@ -15,27 +11,19 @@ export const fetchAutocommitProgressInitAction = createSingleArtifactAction(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchAutocommitProgressSuccessAction = createSingleArtifactAction(
|
export const fetchAutocommitProgressSuccessAction = createSingleArtifactAction(
|
||||||
(
|
(state) => {
|
||||||
state,
|
|
||||||
action: GitArtifactPayloadAction<{
|
|
||||||
autocommitProgress: GitAutocommitProgress;
|
|
||||||
}>,
|
|
||||||
) => {
|
|
||||||
state.apiResponses.autocommitProgress.loading = false;
|
state.apiResponses.autocommitProgress.loading = false;
|
||||||
state.apiResponses.autocommitProgress.value =
|
|
||||||
action.payload.autocommitProgress;
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchAutocommitProgressErrorAction = createSingleArtifactAction(
|
export const fetchAutocommitProgressErrorAction =
|
||||||
(state, action: GitArtifactErrorPayloadAction) => {
|
createSingleArtifactAction<GitAsyncErrorPayload>((state, action) => {
|
||||||
const { error } = action.payload;
|
const { error } = action.payload;
|
||||||
|
|
||||||
state.apiResponses.autocommitProgress.loading = false;
|
state.apiResponses.autocommitProgress.loading = false;
|
||||||
state.apiResponses.autocommitProgress.error = error;
|
state.apiResponses.autocommitProgress.error = error;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
|
||||||
31
app/client/src/git/store/actions/fetchGitMetadataActions.ts
Normal file
31
app/client/src/git/store/actions/fetchGitMetadataActions.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types";
|
||||||
|
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
||||||
|
import type { FetchGitMetadataResponseData } from "git/requests/fetchGitMetadataRequest.types";
|
||||||
|
|
||||||
|
export const fetchGitMetadataInitAction = createSingleArtifactAction(
|
||||||
|
(state) => {
|
||||||
|
state.apiResponses.metadata.loading = true;
|
||||||
|
state.apiResponses.metadata.error = null;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchGitMetadataSuccessAction = createSingleArtifactAction<
|
||||||
|
GitAsyncSuccessPayload<FetchGitMetadataResponseData>
|
||||||
|
>((state, action) => {
|
||||||
|
state.apiResponses.metadata.loading = false;
|
||||||
|
state.apiResponses.metadata.value = action.payload.responseData;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const fetchGitMetadataErrorAction =
|
||||||
|
createSingleArtifactAction<GitAsyncErrorPayload>((state, action) => {
|
||||||
|
const { error } = action.payload;
|
||||||
|
|
||||||
|
state.apiResponses.metadata.loading = false;
|
||||||
|
state.apiResponses.metadata.error = error;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import type {
|
|
||||||
GitArtifactPayloadAction,
|
|
||||||
GitArtifactErrorPayloadAction,
|
|
||||||
GitMetadata,
|
|
||||||
} from "../types";
|
|
||||||
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
|
||||||
|
|
||||||
export const fetchMetadataInitAction = createSingleArtifactAction((state) => {
|
|
||||||
state.apiResponses.metadata.loading = true;
|
|
||||||
state.apiResponses.metadata.error = null;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
|
|
||||||
export const fetchMetadataSuccessAction = createSingleArtifactAction(
|
|
||||||
(state, action: GitArtifactPayloadAction<{ metadata: GitMetadata }>) => {
|
|
||||||
state.apiResponses.metadata.loading = false;
|
|
||||||
state.apiResponses.metadata.value = action.payload.metadata;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export const fetchMetadataErrorAction = createSingleArtifactAction(
|
|
||||||
(state, action: GitArtifactErrorPayloadAction) => {
|
|
||||||
const { error } = action.payload;
|
|
||||||
|
|
||||||
state.apiResponses.metadata.loading = false;
|
|
||||||
state.apiResponses.metadata.error = error;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
import type {
|
import type { GitAsyncSuccessPayload, GitAsyncErrorPayload } from "../types";
|
||||||
GitArtifactPayloadAction,
|
|
||||||
GitArtifactErrorPayloadAction,
|
|
||||||
GitProtectedBranches,
|
|
||||||
} from "../types";
|
|
||||||
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
||||||
|
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
|
||||||
|
|
||||||
export const fetchProtectedBranchesInitAction = createSingleArtifactAction(
|
export const fetchProtectedBranchesInitAction = createSingleArtifactAction(
|
||||||
(state) => {
|
(state) => {
|
||||||
|
|
@ -14,28 +11,21 @@ export const fetchProtectedBranchesInitAction = createSingleArtifactAction(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchProtectedBranchesSuccessAction = createSingleArtifactAction(
|
export const fetchProtectedBranchesSuccessAction = createSingleArtifactAction<
|
||||||
(
|
GitAsyncSuccessPayload<FetchProtectedBranchesResponseData>
|
||||||
state,
|
>((state, action) => {
|
||||||
action: GitArtifactPayloadAction<{
|
state.apiResponses.protectedBranches.loading = false;
|
||||||
protectedBranches: GitProtectedBranches;
|
state.apiResponses.protectedBranches.value = action.payload.responseData;
|
||||||
}>,
|
|
||||||
) => {
|
|
||||||
state.apiResponses.protectedBranches.loading = false;
|
|
||||||
state.apiResponses.protectedBranches.value =
|
|
||||||
action.payload.protectedBranches;
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const fetchProtectedBranchesErrorAction = createSingleArtifactAction(
|
export const fetchProtectedBranchesErrorAction =
|
||||||
(state, action: GitArtifactErrorPayloadAction) => {
|
createSingleArtifactAction<GitAsyncErrorPayload>((state, action) => {
|
||||||
const { error } = action.payload;
|
const { error } = action.payload;
|
||||||
|
|
||||||
state.apiResponses.protectedBranches.loading = false;
|
state.apiResponses.protectedBranches.loading = false;
|
||||||
state.apiResponses.protectedBranches.error = error;
|
state.apiResponses.protectedBranches.error = error;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
|
||||||
15
app/client/src/git/store/actions/initGitActions.ts
Normal file
15
app/client/src/git/store/actions/initGitActions.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import type { FetchGitMetadataResponseData } from "git/requests/fetchGitMetadataRequest.types";
|
||||||
|
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
||||||
|
|
||||||
|
export interface InitGitForEditorPayload {
|
||||||
|
artifact: {
|
||||||
|
id: string;
|
||||||
|
baseId: string;
|
||||||
|
gitApplicationMetadata?: Partial<FetchGitMetadataResponseData>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initGitForEditorAction =
|
||||||
|
createSingleArtifactAction<InitGitForEditorPayload>((state) => {
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction";
|
||||||
import type { GitArtifactErrorPayloadAction } from "../types";
|
import type { GitAsyncErrorPayload } from "../types";
|
||||||
|
|
||||||
export const triggerAutocommitInitAction = createSingleArtifactAction(
|
export interface TriggerAutocommitInitPayload {
|
||||||
(state) => {
|
artifactId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const triggerAutocommitInitAction =
|
||||||
|
createSingleArtifactAction<TriggerAutocommitInitPayload>((state) => {
|
||||||
state.apiResponses.triggerAutocommit.loading = true;
|
state.apiResponses.triggerAutocommit.loading = true;
|
||||||
state.apiResponses.triggerAutocommit.error = null;
|
state.apiResponses.triggerAutocommit.error = null;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const triggerAutocommitSuccessAction = createSingleArtifactAction(
|
export const triggerAutocommitSuccessAction = createSingleArtifactAction(
|
||||||
(state) => {
|
(state) => {
|
||||||
|
|
@ -18,13 +21,28 @@ export const triggerAutocommitSuccessAction = createSingleArtifactAction(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const triggerAutocommitErrorAction = createSingleArtifactAction(
|
export const triggerAutocommitErrorAction =
|
||||||
(state, action: GitArtifactErrorPayloadAction) => {
|
createSingleArtifactAction<GitAsyncErrorPayload>((state, action) => {
|
||||||
const { error } = action.payload;
|
const { error } = action.payload;
|
||||||
|
|
||||||
state.apiResponses.triggerAutocommit.loading = false;
|
state.apiResponses.triggerAutocommit.loading = false;
|
||||||
state.apiResponses.triggerAutocommit.error = error;
|
state.apiResponses.triggerAutocommit.error = error;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const pollAutocommitProgressStartAction = createSingleArtifactAction(
|
||||||
|
(state) => {
|
||||||
|
state.ui.autocommitPolling = true;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const pollAutocommitProgressStopAction = createSingleArtifactAction(
|
||||||
|
(state) => {
|
||||||
|
state.ui.autocommitPolling = false;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import {
|
||||||
connectSuccessAction,
|
connectSuccessAction,
|
||||||
} from "./actions/connectActions";
|
} from "./actions/connectActions";
|
||||||
import {
|
import {
|
||||||
fetchMetadataErrorAction,
|
fetchGitMetadataErrorAction,
|
||||||
fetchMetadataInitAction,
|
fetchGitMetadataInitAction,
|
||||||
fetchMetadataSuccessAction,
|
fetchGitMetadataSuccessAction,
|
||||||
} from "./actions/fetchMetadataActions";
|
} from "./actions/fetchGitMetadataActions";
|
||||||
import {
|
import {
|
||||||
fetchBranchesErrorAction,
|
fetchBranchesErrorAction,
|
||||||
fetchBranchesInitAction,
|
fetchBranchesInitAction,
|
||||||
|
|
@ -79,6 +79,34 @@ import {
|
||||||
mergeInitAction,
|
mergeInitAction,
|
||||||
mergeSuccessAction,
|
mergeSuccessAction,
|
||||||
} from "./actions/mergeActions";
|
} from "./actions/mergeActions";
|
||||||
|
import {
|
||||||
|
pollAutocommitProgressStopAction,
|
||||||
|
pollAutocommitProgressStartAction,
|
||||||
|
triggerAutocommitErrorAction,
|
||||||
|
triggerAutocommitInitAction,
|
||||||
|
triggerAutocommitSuccessAction,
|
||||||
|
} from "./actions/triggerAutocommitActions";
|
||||||
|
import {
|
||||||
|
toggleAutocommitErrorAction,
|
||||||
|
toggleAutocommitInitAction,
|
||||||
|
toggleAutocommitSuccessAction,
|
||||||
|
} from "./actions/toggleAutocommitActions";
|
||||||
|
import {
|
||||||
|
fetchProtectedBranchesErrorAction,
|
||||||
|
fetchProtectedBranchesInitAction,
|
||||||
|
fetchProtectedBranchesSuccessAction,
|
||||||
|
} from "./actions/fetchProtectedBranchesActions";
|
||||||
|
import {
|
||||||
|
updateProtectedBranchesErrorAction,
|
||||||
|
updateProtectedBranchesInitAction,
|
||||||
|
updateProtectedBranchesSuccessAction,
|
||||||
|
} from "./actions/updateProtectedBranchesActions";
|
||||||
|
import { initGitForEditorAction } from "./actions/initGitActions";
|
||||||
|
import {
|
||||||
|
fetchAutocommitProgressErrorAction,
|
||||||
|
fetchAutocommitProgressInitAction,
|
||||||
|
fetchAutocommitProgressSuccessAction,
|
||||||
|
} from "./actions/fetchAutocommitProgressActions";
|
||||||
|
|
||||||
const initialState: GitArtifactReduxState = {};
|
const initialState: GitArtifactReduxState = {};
|
||||||
|
|
||||||
|
|
@ -87,8 +115,13 @@ export const gitArtifactSlice = createSlice({
|
||||||
reducerPath: "git.artifact",
|
reducerPath: "git.artifact",
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
|
// init
|
||||||
|
initGitForEditor: initGitForEditorAction,
|
||||||
mount: mountAction,
|
mount: mountAction,
|
||||||
unmount: unmountAction,
|
unmount: unmountAction,
|
||||||
|
fetchGitMetadataInit: fetchGitMetadataInitAction,
|
||||||
|
fetchGitMetadataSuccess: fetchGitMetadataSuccessAction,
|
||||||
|
fetchGitMetadataError: fetchGitMetadataErrorAction,
|
||||||
|
|
||||||
// connect
|
// connect
|
||||||
connectInit: connectInitAction,
|
connectInit: connectInitAction,
|
||||||
|
|
@ -135,17 +168,31 @@ export const gitArtifactSlice = createSlice({
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
toggleGitSettingsModal: toggleGitSettingsModalAction,
|
toggleGitSettingsModal: toggleGitSettingsModalAction,
|
||||||
|
|
||||||
// metadata
|
|
||||||
fetchMetadataInit: fetchMetadataInitAction,
|
|
||||||
fetchMetadataSuccess: fetchMetadataSuccessAction,
|
|
||||||
fetchMetadataError: fetchMetadataErrorAction,
|
|
||||||
fetchLocalProfileInit: fetchLocalProfileInitAction,
|
fetchLocalProfileInit: fetchLocalProfileInitAction,
|
||||||
fetchLocalProfileSuccess: fetchLocalProfileSuccessAction,
|
fetchLocalProfileSuccess: fetchLocalProfileSuccessAction,
|
||||||
fetchLocalProfileError: fetchLocalProfileErrorAction,
|
fetchLocalProfileError: fetchLocalProfileErrorAction,
|
||||||
updateLocalProfileInit: updateLocalProfileInitAction,
|
updateLocalProfileInit: updateLocalProfileInitAction,
|
||||||
updateLocalProfileSuccess: updateLocalProfileSuccessAction,
|
updateLocalProfileSuccess: updateLocalProfileSuccessAction,
|
||||||
updateLocalProfileError: updateLocalProfileErrorAction,
|
updateLocalProfileError: updateLocalProfileErrorAction,
|
||||||
|
fetchProtectedBranchesInit: fetchProtectedBranchesInitAction,
|
||||||
|
fetchProtectedBranchesSuccess: fetchProtectedBranchesSuccessAction,
|
||||||
|
fetchProtectedBranchesError: fetchProtectedBranchesErrorAction,
|
||||||
|
updateProtectedBranchesInit: updateProtectedBranchesInitAction,
|
||||||
|
updateProtectedBranchesSuccess: updateProtectedBranchesSuccessAction,
|
||||||
|
updateProtectedBranchesError: updateProtectedBranchesErrorAction,
|
||||||
|
|
||||||
|
// autocommit
|
||||||
|
toggleAutocommitInit: toggleAutocommitInitAction,
|
||||||
|
toggleAutocommitSuccess: toggleAutocommitSuccessAction,
|
||||||
|
toggleAutocommitError: toggleAutocommitErrorAction,
|
||||||
|
triggerAutocommitInit: triggerAutocommitInitAction,
|
||||||
|
triggerAutocommitSuccess: triggerAutocommitSuccessAction,
|
||||||
|
triggerAutocommitError: triggerAutocommitErrorAction,
|
||||||
|
fetchAutocommitProgressInit: fetchAutocommitProgressInitAction,
|
||||||
|
fetchAutocommitProgressSuccess: fetchAutocommitProgressSuccessAction,
|
||||||
|
fetchAutocommitProgressError: fetchAutocommitProgressErrorAction,
|
||||||
|
pollAutocommitProgressStart: pollAutocommitProgressStartAction,
|
||||||
|
pollAutocommitProgressStop: pollAutocommitProgressStopAction,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ const gitSingleArtifactInitialUIState: GitSingleArtifactUIReduxState = {
|
||||||
repoLimitErrorModal: {
|
repoLimitErrorModal: {
|
||||||
open: false,
|
open: false,
|
||||||
},
|
},
|
||||||
|
autocommitModalOpen: false,
|
||||||
|
autocommitPolling: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const gitSingleArtifactInitialAPIResponses: GitSingleArtifactAPIResponsesReduxState =
|
const gitSingleArtifactInitialAPIResponses: GitSingleArtifactAPIResponsesReduxState =
|
||||||
|
|
@ -112,7 +114,6 @@ const gitSingleArtifactInitialAPIResponses: GitSingleArtifactAPIResponsesReduxSt
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
autocommitProgress: {
|
autocommitProgress: {
|
||||||
value: null,
|
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,17 @@ export const selectSingleArtifact = (
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// metadata
|
||||||
|
export const selectGitMetadata = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => selectSingleArtifact(state, artifactDef)?.apiResponses.metadata;
|
||||||
|
|
||||||
|
export const selectGitConnected = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => !!selectGitMetadata(state, artifactDef).value;
|
||||||
|
|
||||||
// git ops
|
// git ops
|
||||||
export const selectCommit = (
|
export const selectCommit = (
|
||||||
state: GitRootState,
|
state: GitRootState,
|
||||||
|
|
@ -43,6 +54,16 @@ export const selectPull = (state: GitRootState, artifactDef: GitArtifactDef) =>
|
||||||
selectSingleArtifact(state, artifactDef)?.apiResponses?.pull;
|
selectSingleArtifact(state, artifactDef)?.apiResponses?.pull;
|
||||||
|
|
||||||
// git branches
|
// git branches
|
||||||
|
|
||||||
|
export const selectCurrentBranch = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => {
|
||||||
|
const gitMetadataState = selectGitMetadata(state, artifactDef).value;
|
||||||
|
|
||||||
|
return gitMetadataState?.branchName;
|
||||||
|
};
|
||||||
|
|
||||||
export const selectBranches = (
|
export const selectBranches = (
|
||||||
state: GitRootState,
|
state: GitRootState,
|
||||||
artifactDef: GitArtifactDef,
|
artifactDef: GitArtifactDef,
|
||||||
|
|
@ -62,3 +83,34 @@ export const selectCheckoutBranch = (
|
||||||
state: GitRootState,
|
state: GitRootState,
|
||||||
artifactDef: GitArtifactDef,
|
artifactDef: GitArtifactDef,
|
||||||
) => selectSingleArtifact(state, artifactDef)?.apiResponses.checkoutBranch;
|
) => selectSingleArtifact(state, artifactDef)?.apiResponses.checkoutBranch;
|
||||||
|
|
||||||
|
// autocommit
|
||||||
|
export const selectAutocommitEnabled = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => {
|
||||||
|
const gitMetadata = selectGitMetadata(state, artifactDef).value;
|
||||||
|
|
||||||
|
return gitMetadata?.autoCommitConfig?.enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const selectAutocommitPolling = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => selectSingleArtifact(state, artifactDef)?.ui.autocommitPolling;
|
||||||
|
|
||||||
|
// protected branches
|
||||||
|
export const selectProtectedBranches = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => selectSingleArtifact(state, artifactDef)?.apiResponses.protectedBranches;
|
||||||
|
|
||||||
|
export const selectProtectedMode = (
|
||||||
|
state: GitRootState,
|
||||||
|
artifactDef: GitArtifactDef,
|
||||||
|
) => {
|
||||||
|
const currentBranch = selectCurrentBranch(state, artifactDef);
|
||||||
|
const protectedBranches = selectProtectedBranches(state, artifactDef).value;
|
||||||
|
|
||||||
|
return protectedBranches?.includes(currentBranch ?? "");
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,8 @@ import type { FetchBranchesResponseData } from "../requests/fetchBranchesRequest
|
||||||
import type { FetchLocalProfileResponseData } from "../requests/fetchLocalProfileRequest.types";
|
import type { FetchLocalProfileResponseData } from "../requests/fetchLocalProfileRequest.types";
|
||||||
import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types";
|
import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types";
|
||||||
import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types";
|
import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types";
|
||||||
|
import type { FetchGitMetadataResponseData } from "git/requests/fetchGitMetadataRequest.types";
|
||||||
// These will be updated when contracts are finalized
|
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
|
||||||
export type GitMetadata = Record<string, unknown>;
|
|
||||||
|
|
||||||
export type GitProtectedBranches = Record<string, unknown>;
|
|
||||||
|
|
||||||
export type GitAutocommitProgress = Record<string, unknown>;
|
|
||||||
|
|
||||||
export type GitSSHKey = Record<string, unknown>;
|
export type GitSSHKey = Record<string, unknown>;
|
||||||
|
|
||||||
|
|
@ -32,7 +27,7 @@ interface AsyncStateWithoutValue {
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
}
|
||||||
export interface GitSingleArtifactAPIResponsesReduxState {
|
export interface GitSingleArtifactAPIResponsesReduxState {
|
||||||
metadata: AsyncState<GitMetadata>;
|
metadata: AsyncState<FetchGitMetadataResponseData>;
|
||||||
connect: AsyncStateWithoutValue;
|
connect: AsyncStateWithoutValue;
|
||||||
status: AsyncState<FetchStatusResponseData>;
|
status: AsyncState<FetchStatusResponseData>;
|
||||||
commit: AsyncStateWithoutValue;
|
commit: AsyncStateWithoutValue;
|
||||||
|
|
@ -47,9 +42,9 @@ export interface GitSingleArtifactAPIResponsesReduxState {
|
||||||
localProfile: AsyncState<FetchLocalProfileResponseData>;
|
localProfile: AsyncState<FetchLocalProfileResponseData>;
|
||||||
updateLocalProfile: AsyncStateWithoutValue;
|
updateLocalProfile: AsyncStateWithoutValue;
|
||||||
disconnect: AsyncStateWithoutValue;
|
disconnect: AsyncStateWithoutValue;
|
||||||
protectedBranches: AsyncState<GitProtectedBranches>;
|
protectedBranches: AsyncState<FetchProtectedBranchesResponseData>;
|
||||||
updateProtectedBranches: AsyncStateWithoutValue;
|
updateProtectedBranches: AsyncStateWithoutValue;
|
||||||
autocommitProgress: AsyncState<GitAutocommitProgress>;
|
autocommitProgress: AsyncStateWithoutValue;
|
||||||
toggleAutocommit: AsyncStateWithoutValue;
|
toggleAutocommit: AsyncStateWithoutValue;
|
||||||
triggerAutocommit: AsyncStateWithoutValue;
|
triggerAutocommit: AsyncStateWithoutValue;
|
||||||
sshKey: AsyncState<GitSSHKey>;
|
sshKey: AsyncState<GitSSHKey>;
|
||||||
|
|
@ -79,6 +74,8 @@ export interface GitSingleArtifactUIReduxState {
|
||||||
repoLimitErrorModal: {
|
repoLimitErrorModal: {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
};
|
};
|
||||||
|
autocommitPolling: boolean;
|
||||||
|
autocommitModalOpen: boolean;
|
||||||
}
|
}
|
||||||
export interface GitSingleArtifactReduxState {
|
export interface GitSingleArtifactReduxState {
|
||||||
ui: GitSingleArtifactUIReduxState;
|
ui: GitSingleArtifactUIReduxState;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user