hunk.code_window:   flex-basis: ${(props) =>
       props.theme.homePage.leftPane.width +
       props.theme.homePage.leftPane.leftPadding}px;
     padding: 0 0 0 ${(props) => props.theme.homePage.leftPane.leftPadding}px;
   `;
   export const HeaderContainer = styled.div``;
  
hunk.labels: keep keep keep add keep keep keep keep
hunk.after_edit:   overflow-y: auto;
     &::-webkit-scrollbar {
       display: none;
     }
  
hunk.file_path: app/client/src/ce/pages/AdminSettings/LeftPane.tsx
hunk.type: add
file: import React, { useState, useEffect } from "react";
  import styled from "styled-components";
  import {
    ActionButton,
    SaveButtonContainer,
  } from "pages/Editor/DataSourceEditor/JSONtoForm";
  import { useDispatch, useSelector } from "react-redux";
  import {
    getEntities,
    getPluginTypeFromDatasourceId,
  } from "selectors/entitiesSelector";
  import {
    testDatasource,
    deleteDatasource,
    updateDatasource,
    redirectAuthorizationCode,
    getOAuthAccessToken,
    setDatasourceViewMode,
    createDatasourceFromForm,
    toggleSaveActionFlag,
  } from "actions/datasourceActions";
  import AnalyticsUtil from "utils/AnalyticsUtil";
  import { getCurrentApplicationId } from "selectors/editorSelectors";
  import { useParams, useLocation } from "react-router";
  import { ExplorerURLParams } from "pages/Editor/Explorer/helpers";
  import { AppState } from "@appsmith/reducers";
  import {
    AuthType,
    Datasource,
    AuthenticationStatus,
  } from "entities/Datasource";
  import {
    OAUTH_AUTHORIZATION_APPSMITH_ERROR,
    OAUTH_AUTHORIZATION_FAILED,
  } from "@appsmith/constants/messages";
  import { Category, Toaster, Variant } from "design-system";
  import {
    CONTEXT_DELETE,
    CONFIRM_CONTEXT_DELETE,
    createMessage,
  } from "@appsmith/constants/messages";
  import { debounce } from "lodash";
  import { TEMP_DATASOURCE_ID } from "constants/Datasource";
  
  import {
    hasDeleteDatasourcePermission,
    hasManageDatasourcePermission,
  } from "@appsmith/utils/permissionHelpers";
  
  interface Props {
    datasource: Datasource;
    formData: Datasource;
    getSanitizedFormData: () => Datasource;
    isInvalid: boolean;
    pageId?: string;
    shouldRender: boolean;
    datasourceButtonConfiguration: string[] | undefined;
    triggerSave?: boolean;
    isFormDirty?: boolean;
    datasourceDeleteTrigger: () => void;
  }
  
  export type DatasourceFormButtonTypes = Record<string, string[]>;
  
  enum AuthorizationStatus {
    SUCCESS = "success",
    APPSMITH_ERROR = "appsmith_error",
  }
  
  export enum DatasourceButtonTypeEnum {
    DELETE = "DELETE",
    SAVE = "SAVE",
    TEST = "TEST",
    SAVE_AND_AUTHORIZE = "SAVE_AND_AUTHORIZE",
  }
  
  export const DatasourceButtonType: Record<
    keyof typeof DatasourceButtonTypeEnum,
    string
  > = {
    DELETE: "DELETE",
    SAVE: "SAVE",
    TEST: "TEST",
    SAVE_AND_AUTHORIZE: "SAVE_AND_AUTHORIZE",
  };
  
  const StyledButton = styled(ActionButton)<{ fluidWidth?: boolean }>`
    &&&& {
      height: 32px;
      width: ${(props) => (props.fluidWidth ? "" : "87px")};
    }
  `;
  
  const StyledAuthMessage = styled.div`
    color: ${(props) => props.theme.colors.error};
    margin-top: 15px;
    &:after {
      content: " *";
      color: inherit;
    }
  `;
  
  function DatasourceAuth({
    datasource,
    datasourceButtonConfiguration = ["DELETE", "SAVE"],
    datasourceDeleteTrigger,
    formData,
    getSanitizedFormData,
    isInvalid,
    pageId: pageIdProp,
    shouldRender,
    triggerSave,
    isFormDirty,
  }: Props) {
    const authType =
      formData &&
      formData?.datasourceConfiguration?.authentication?.authenticationType;
  
    const { id: datasourceId, isDeleting } = datasource;
    const applicationId = useSelector(getCurrentApplicationId);
  
    const datasourcePermissions = datasource.userPermissions || [];
  
    const canManageDatasource = hasManageDatasourcePermission(
      datasourcePermissions,
    );
  
    const canDeleteDatasource = hasDeleteDatasourcePermission(
      datasourcePermissions,
    );
  
    // hooks
    const dispatch = useDispatch();
    const location = useLocation();
    const { pageId: pageIdQuery } = useParams<ExplorerURLParams>();
  
    const pageId = (pageIdQuery || pageIdProp) as string;
    const [confirmDelete, setConfirmDelete] = useState(false);
  
    useEffect(() => {
      if (confirmDelete) {
        delayConfirmDeleteToFalse();
      }
    }, [confirmDelete]);
  
    useEffect(() => {
      if (authType === AuthType.OAUTH2) {
        // When the authorization server redirects a user to the datasource form page, the url contains the "response_status" query parameter .
        // Get the access token if response_status is successful else show a toast error
  
        const search = new URLSearchParams(location.search);
        const status = search.get("response_status");
        const queryIsImport = search.get("importForGit");
        const queryDatasourceId = search.get("datasourceId");
        const shouldNotify =
          !queryIsImport || (queryIsImport && queryDatasourceId === datasourceId);
        if (status && shouldNotify) {
          const display_message = search.get("display_message");
          const variant = Variant.danger;
  
          if (status !== AuthorizationStatus.SUCCESS) {
            const message =
              status === AuthorizationStatus.APPSMITH_ERROR
                ? OAUTH_AUTHORIZATION_APPSMITH_ERROR
                : OAUTH_AUTHORIZATION_FAILED;
            Toaster.show({ text: display_message || message, variant });
          } else {
            dispatch(getOAuthAccessToken(datasourceId));
          }
          AnalyticsUtil.logEvent("DATASOURCE_AUTH_COMPLETE", {
            applicationId,
            datasourceId,
            pageId,
          });
        }
      }
    }, [authType]);
  
    // selectors
    const {
      datasources: { isTesting, loading: isSaving },
    } = useSelector(getEntities);
  
    const delayConfirmDeleteToFalse = debounce(
      () => setConfirmDelete(false),
      2200,
    );
  
    const pluginType = useSelector((state: AppState) =>
      getPluginTypeFromDatasourceId(state, datasourceId),
    );
  
    useEffect(() => {
      if (triggerSave) {
        if (pluginType === "SAAS") {
          handleOauthDatasourceSave();
        } else {
          handleDefaultAuthDatasourceSave();
        }
      }
    }, [triggerSave]);
  
    const isAuthorized =
      datasource?.datasourceConfiguration?.authentication
        ?.authenticationStatus === AuthenticationStatus.SUCCESS;
  
    // Button Operations for respective buttons.
  
    // Handles datasource deletion
    const handleDatasourceDelete = () => {
      dispatch(deleteDatasource({ id: datasourceId }));
      datasourceDeleteTrigger();
    };
  
    // Handles datasource testing
    const handleDatasourceTest = () => {
      AnalyticsUtil.logEvent("TEST_DATA_SOURCE_CLICK", {
        pageId: pageId,
        appId: applicationId,
      });
      dispatch(testDatasource(getSanitizedFormData()));
    };
  
    // Handles default auth datasource saving
    const handleDefaultAuthDatasourceSave = () => {
      dispatch(toggleSaveActionFlag(true));
      AnalyticsUtil.logEvent("SAVE_DATA_SOURCE_CLICK", {
        pageId: pageId,
        appId: applicationId,
      });
      // After saving datasource, only redirect to the 'new integrations' page
      // if datasource is not used to generate a page
      if (datasource.id === TEMP_DATASOURCE_ID) {
        dispatch(createDatasourceFromForm(getSanitizedFormData()));
      } else {
        dispatch(setDatasourceViewMode(true));
        // we dont need to redirect it to active ds list instead ds would be shown in view only mode
        dispatch(updateDatasource(getSanitizedFormData()));
      }
    };
  
    // Handles Oauth datasource saving
    const handleOauthDatasourceSave = () => {
      dispatch(toggleSaveActionFlag(true));
      if (datasource.id === TEMP_DATASOURCE_ID) {
        dispatch(
          createDatasourceFromForm(
            getSanitizedFormData(),
            pluginType
              ? redirectAuthorizationCode(pageId, datasourceId, pluginType)
              : undefined,
          ),
        );
      } else {
        dispatch(setDatasourceViewMode(true));
        dispatch(
          updateDatasource(
            getSanitizedFormData(),
            pluginType
              ? redirectAuthorizationCode(pageId, datasourceId, pluginType)
              : undefined,
          ),
        );
      }
    };
  
    const createMode = datasourceId === TEMP_DATASOURCE_ID;
  
    const datasourceButtonsComponentMap = (buttonType: string): JSX.Element => {
      return {
        [DatasourceButtonType.DELETE]: (
          <ActionButton
            category={Category.primary}
            className="t--delete-datasource"
            disabled={createMode || !canDeleteDatasource}
            key={buttonType}
            loading={isDeleting}
            onClick={() => {
              confirmDelete ? handleDatasourceDelete() : setConfirmDelete(true);
            }}
            size="medium"
            tag="button"
            text={
              confirmDelete && !isDeleting
                ? createMessage(CONFIRM_CONTEXT_DELETE)
                : createMessage(CONTEXT_DELETE)
            }
            variant={Variant.danger}
          />
        ),
        [DatasourceButtonType.TEST]: (
          <ActionButton
            category={Category.secondary}
            className="t--test-datasource"
            isLoading={isTesting}
            key={buttonType}
            onClick={handleDatasourceTest}
            size="medium"
            tag="button"
            text="Test"
            variant={Variant.success}
          />
        ),
        [DatasourceButtonType.SAVE]: (
          <ActionButton
            category={Category.primary}
            className="t--save-datasource"
            disabled={
              isInvalid || !isFormDirty || (!createMode && !canManageDatasource)
            }
            filled
            key={buttonType}
            loading={isSaving}
            onClick={handleDefaultAuthDatasourceSave}
            size="medium"
            tag="button"
            text="Save"
            variant={Variant.success}
          />
        ),
        [DatasourceButtonType.SAVE_AND_AUTHORIZE]: (
          <StyledButton
            category={Category.primary}
            className="t--save-datasource"
            disabled={isInvalid || (!createMode && !canManageDatasource)}
            filled
            fluidWidth
            isLoading={isSaving}
            key={buttonType}
            onClick={handleOauthDatasourceSave}
            size="medium"
            tag="button"
            text={isAuthorized ? "Save and Re-authorize" : "Save and Authorize"}
            variant={Variant.success}
          />
        ),
      }[buttonType];
    };
  
    return (
      <>
        {authType === AuthType.OAUTH2 && !isAuthorized && (
          <StyledAuthMessage>Datasource not authorized</StyledAuthMessage>
        )}
        {shouldRender && (
          <SaveButtonContainer>
            {datasourceButtonConfiguration?.map((btnConfig) =>
              datasourceButtonsComponentMap(btnConfig),
            )}
          </SaveButtonContainer>
        )}
        {""}
      </>
    );
  }
  
  export default DatasourceAuth;
  