From 5a9ad24f929334bb5203815af28cd133468637f4 Mon Sep 17 00:00:00 2001
From: Alexander Polyankin <alexander.polyankin@metabase.com>
Date: Wed, 12 Jan 2022 18:05:57 +0300
Subject: [PATCH] Inline deprecated driver warning (#19636)

---
 .../src/metabase-types/api/mocks/settings.ts  |  33 +++++-
 frontend/src/metabase-types/api/settings.ts   |  30 +++--
 .../metabase-types/store/mocks/settings.ts    |   3 +-
 .../DeprecationNotice/DeprecationNotice.tsx   |   4 +-
 .../databases/containers/DatabaseEditApp.jsx  |  31 +++---
 .../containers/DatabaseEditApp.unit.spec.js   |   3 +
 .../src/metabase/admin/databases/database.js  |  23 ----
 .../DriverWarning/DriverWarning.jsx           | 103 ------------------
 .../DriverWarning/DriverWarning.stories.tsx   |  37 +++++++
 .../DriverWarning/DriverWarning.styled.jsx    |  48 --------
 .../DriverWarning/DriverWarning.styled.tsx    |  22 ++++
 .../DriverWarning/DriverWarning.tsx           |  62 +++++++++++
 .../DriverWarning/DriverWarning.unit.spec.tsx |  39 +++++++
 .../DriverWarning/{index.js => index.ts}      |   0
 .../DriverWarning/DriverWarning.tsx           |  25 +++++
 .../containers/DriverWarning/index.ts         |   1 +
 frontend/src/metabase/css/admin.css           |   2 +-
 .../components/DatabaseStep/DatabaseStep.tsx  |  19 +++-
 .../DatabaseStep/DatabaseStep.unit.spec.tsx   |   8 +-
 .../setup/components/DatabaseStep/types.ts    |   8 +-
 .../admin/databases/add-presto.cy.spec.js     |  12 +-
 .../scenarios/admin/databases/add.cy.spec.js  |   2 +-
 22 files changed, 293 insertions(+), 222 deletions(-)
 delete mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.jsx
 create mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.stories.tsx
 delete mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.styled.jsx
 create mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.styled.tsx
 create mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.tsx
 create mode 100644 frontend/src/metabase/components/DriverWarning/DriverWarning.unit.spec.tsx
 rename frontend/src/metabase/components/DriverWarning/{index.js => index.ts} (100%)
 create mode 100644 frontend/src/metabase/containers/DriverWarning/DriverWarning.tsx
 create mode 100644 frontend/src/metabase/containers/DriverWarning/index.ts

diff --git a/frontend/src/metabase-types/api/mocks/settings.ts b/frontend/src/metabase-types/api/mocks/settings.ts
index 1851e7d902a..e561d9aa800 100644
--- a/frontend/src/metabase-types/api/mocks/settings.ts
+++ b/frontend/src/metabase-types/api/mocks/settings.ts
@@ -1,5 +1,36 @@
-import { Settings } from "metabase-types/api";
+import { Engine, Settings, Version } from "metabase-types/api";
+
+export const createMockEngine = (opts?: Partial<Engine>): Engine => ({
+  "driver-name": "PostgreSQL",
+  "superseded-by": undefined,
+  ...opts,
+});
+
+export const createMockEngines = (
+  opts?: Record<string, Engine>,
+): Record<string, Engine> => ({
+  postgres: createMockEngine(),
+  ...opts,
+});
+
+export const createMockVersion = (opts?: Partial<Version>): Version => ({
+  tag: "v1",
+  ...opts,
+});
 
 export const createMockSettings = (opts?: Partial<Settings>): Settings => ({
+  "enable-public-sharing": false,
+  "enable-xrays": false,
+  engines: createMockEngines(),
+  "deprecation-notice-version": undefined,
+  "show-database-syncing-modal": false,
+  "show-homepage-data": false,
+  "show-homepage-xrays": false,
+  "show-homepage-pin-message": false,
+  "slack-token": undefined,
+  "slack-token-valid?": false,
+  "slack-app-token": undefined,
+  "slack-files-channel": undefined,
+  version: createMockVersion(),
   ...opts,
 });
diff --git a/frontend/src/metabase-types/api/settings.ts b/frontend/src/metabase-types/api/settings.ts
index 5637c3228f0..199b809ec5f 100644
--- a/frontend/src/metabase-types/api/settings.ts
+++ b/frontend/src/metabase-types/api/settings.ts
@@ -1,18 +1,24 @@
+export interface Engine {
+  "driver-name": string;
+  "superseded-by": string | undefined;
+}
+
 export interface Version {
   tag: string;
 }
 
 export interface Settings {
-  "enable-public-sharing"?: boolean;
-  "enable-xrays"?: boolean;
-  "deprecation-notice-version"?: string;
-  "show-database-syncing-modal"?: boolean;
-  "show-homepage-data"?: boolean;
-  "show-homepage-xrays"?: boolean;
-  "show-homepage-pin-message"?: boolean;
-  "slack-token"?: string;
-  "slack-token-valid?"?: boolean;
-  "slack-app-token"?: string;
-  "slack-files-channel"?: string;
-  version?: Version;
+  "enable-public-sharing": boolean;
+  "enable-xrays": boolean;
+  engines: Record<string, Engine>;
+  "deprecation-notice-version": string | undefined;
+  "show-database-syncing-modal": boolean;
+  "show-homepage-data": boolean;
+  "show-homepage-xrays": boolean;
+  "show-homepage-pin-message": boolean;
+  "slack-token": string | undefined;
+  "slack-token-valid?": boolean;
+  "slack-app-token": string | undefined;
+  "slack-files-channel": string | undefined;
+  version: Version;
 }
diff --git a/frontend/src/metabase-types/store/mocks/settings.ts b/frontend/src/metabase-types/store/mocks/settings.ts
index db1cb318e62..3d31be3c996 100644
--- a/frontend/src/metabase-types/store/mocks/settings.ts
+++ b/frontend/src/metabase-types/store/mocks/settings.ts
@@ -1,8 +1,9 @@
 import { SettingsState } from "metabase-types/store";
+import { createMockSettings } from "metabase-types/api/mocks";
 
 export const createMockSettingsState = (
   opts?: Partial<SettingsState>,
 ): SettingsState => ({
-  values: {},
+  values: createMockSettings(),
   ...opts,
 });
diff --git a/frontend/src/metabase/admin/app/components/DeprecationNotice/DeprecationNotice.tsx b/frontend/src/metabase/admin/app/components/DeprecationNotice/DeprecationNotice.tsx
index 928ba82bbb0..bb166fe138c 100644
--- a/frontend/src/metabase/admin/app/components/DeprecationNotice/DeprecationNotice.tsx
+++ b/frontend/src/metabase/admin/app/components/DeprecationNotice/DeprecationNotice.tsx
@@ -58,12 +58,12 @@ const getBannerContent = (
       <strong key="upgrade">{t`upgrade`}</strong>
     )}.`;
   } else if (hasSlackBot) {
-    return jt`Your Slack bot was deprecated but is still working. We recommend you ${(
+    return jt`Your Slack bot was deprecated but is still working. We recommend you delete the existing connection and ${(
       <NoticeLink
         key="slack"
         to={slackSettingsUrl}
       >{t`upgrade to Slack Apps`}</NoticeLink>
-    )} when you get a chance.`;
+    )}.`;
   } else if (hasDeprecatedDatabase) {
     return jt`You’re using a ${(
       <NoticeLink
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
index c7c14f5f11e..45f19940e92 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
@@ -5,6 +5,7 @@ import { connect } from "react-redux";
 import { getValues } from "redux-form";
 
 import { t } from "ttag";
+import _ from "underscore";
 
 import { Box, Flex } from "grid-styled";
 
@@ -13,8 +14,8 @@ import title from "metabase/hoc/Title";
 import AddDatabaseHelpCard from "metabase/components/AddDatabaseHelpCard";
 import Button from "metabase/components/Button";
 import Breadcrumbs from "metabase/components/Breadcrumbs";
-import DriverWarning from "metabase/components/DriverWarning";
 import Sidebar from "metabase/admin/databases/components/DatabaseEditApp/Sidebar/Sidebar";
+import DriverWarning from "metabase/containers/DriverWarning";
 
 import Databases from "metabase/entities/databases";
 
@@ -131,19 +132,26 @@ export default class DatabaseEditApp extends Component {
                       FormMessage,
                       FormSubmit,
                       formFields,
-                      onChangeField,
+                      values,
                       submitTitle,
+                      onChangeField,
                     }) => {
                       return (
                         <Flex>
                           <Box width={620}>
                             <Form>
-                              {formFields.map(formField => (
-                                <FormField
-                                  key={formField.name}
-                                  name={formField.name}
-                                />
-                              ))}
+                              <FormField name="engine" />
+                              <DriverWarning
+                                engine={values.engine}
+                                onChange={engine =>
+                                  onChangeField("engine", engine)
+                                }
+                              />
+                              {_.reject(formFields, { name: "engine" }).map(
+                                ({ name }) => (
+                                  <FormField key={name} name={name} />
+                                ),
+                              )}
                               <FormMessage />
                               <div className="Form-actions text-centered">
                                 <FormSubmit className="block mb2">
@@ -160,13 +168,6 @@ export default class DatabaseEditApp extends Component {
                                 data-testid="database-setup-help-card"
                               />
                             )}
-                            <DriverWarning
-                              engine={selectedEngine}
-                              ml={26}
-                              onChangeEngine={engine => {
-                                onChangeField("engine", engine);
-                              }}
-                            />
                           </Box>
                         </Flex>
                       );
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.unit.spec.js b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.unit.spec.js
index 467ff4af341..8f802c436de 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.unit.spec.js
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.unit.spec.js
@@ -28,6 +28,9 @@ const ENGINES_MOCK = {
   },
 };
 
+const ComponentMock = () => <div />;
+jest.mock("metabase/containers/DriverWarning", () => ComponentMock);
+
 function mockSettings({ cachingEnabled = false }) {
   const original = MetabaseSettings.get.bind(MetabaseSettings);
   const spy = jest.spyOn(MetabaseSettings, "get");
diff --git a/frontend/src/metabase/admin/databases/database.js b/frontend/src/metabase/admin/databases/database.js
index f2e05a92908..8810570308c 100644
--- a/frontend/src/metabase/admin/databases/database.js
+++ b/frontend/src/metabase/admin/databases/database.js
@@ -64,8 +64,6 @@ export const CLEAR_INITIALIZE_DATABASE_ERROR =
 
 export const CLOSE_SYNCING_MODAL =
   "metabase/admin/databases/CLOSE_SYNCING_MODAL";
-export const CLOSE_DEPRECATION_NOTICE =
-  "metabase/admin/databases/CLOSE_DEPRECATION_NOTICE";
 
 export const reset = createAction(RESET);
 
@@ -294,19 +292,6 @@ export const closeSyncingModal = createThunkAction(
   },
 );
 
-export const closeDeprecationNotice = createThunkAction(
-  CLOSE_DEPRECATION_NOTICE,
-  function() {
-    return async function(dispatch) {
-      const setting = {
-        key: "deprecation-notice-version",
-        value: MetabaseSettings.currentVersion(),
-      };
-      await dispatch(updateSetting(setting));
-    };
-  },
-);
-
 // reducers
 
 const editingDatabase = handleActions(
@@ -367,13 +352,6 @@ const sampleDataset = handleActions(
   { error: undefined, loading: false },
 );
 
-const isDeprecationNoticeEnabled = handleActions(
-  {
-    [CLOSE_DEPRECATION_NOTICE]: () => false,
-  },
-  MetabaseSettings.deprecationNoticeEnabled(),
-);
-
 export default combineReducers({
   editingDatabase,
   initializeError,
@@ -381,5 +359,4 @@ export default combineReducers({
   databaseCreationStep,
   deletes,
   sampleDataset,
-  isDeprecationNoticeEnabled,
 });
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.jsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.jsx
deleted file mode 100644
index 080e49410ee..00000000000
--- a/frontend/src/metabase/components/DriverWarning/DriverWarning.jsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import React from "react";
-import PropTypes from "prop-types";
-
-import { t } from "ttag";
-
-import {
-  allEngines,
-  engineSupersedesMap,
-} from "metabase/entities/databases/forms";
-
-import {
-  CardContent,
-  DriverWarningContainer,
-  IconContainer,
-  Link,
-  WarningIcon,
-  WarningParagraph,
-} from "./DriverWarning.styled";
-
-import Icon from "metabase/components/Icon";
-import MetabaseSettings from "metabase/lib/settings";
-
-const propTypes = {
-  engine: PropTypes.string.isRequired,
-  hasCircle: PropTypes.bool,
-  onChangeEngine: PropTypes.func.isRequired,
-};
-
-const driverUpgradeHelpLink = MetabaseSettings.docsUrl(
-  "administration-guide/01-managing-databases",
-);
-
-function getSupersedesWarningContent(
-  newDriver,
-  supersedesDriver,
-  onChangeEngine,
-) {
-  return (
-    <div>
-      <WarningParagraph>
-        {t`This is our new ${allEngines[newDriver]["driver-name"]} driver, which is faster and more reliable.`}
-      </WarningParagraph>
-
-      <WarningParagraph hasMargin>
-        {t`The old driver has been deprecated and will be removed in a future release. If you really
-      need to use it, you can `}
-        &nbsp;
-        <Link
-          onClick={() => onChangeEngine(supersedesDriver)}
-        >{t`find it here`}</Link>
-        .
-      </WarningParagraph>
-    </div>
-  );
-}
-
-function getSupersededByWarningContent(engine, onChangeEngine) {
-  return (
-    <div>
-      <WarningParagraph>
-        {t`This driver has been deprecated and will be removed in a future release.`}
-      </WarningParagraph>
-      <WarningParagraph hasMargin>
-        {t`We recommend that you upgrade to the`}
-        &nbsp;
-        <Link
-          onClick={() => onChangeEngine(engine)}
-        >{t`new ${allEngines[engine]["driver-name"]} driver`}</Link>
-        {t`, which is faster and more reliable.`}
-      </WarningParagraph>
-      <Link href={driverUpgradeHelpLink} target={"_blank"}>
-        {t`How to upgrade a driver`}
-      </Link>
-    </div>
-  );
-}
-
-function DriverWarning({ engine, hasCircle = true, onChangeEngine, ...props }) {
-  const supersededBy = engineSupersedesMap["superseded_by"][engine];
-  const supersedes = engineSupersedesMap["supersedes"][engine];
-
-  if (!supersedes && !supersededBy) {
-    return null;
-  }
-
-  const warningContent = supersedes
-    ? getSupersedesWarningContent(engine, supersedes, onChangeEngine)
-    : getSupersededByWarningContent(supersededBy, onChangeEngine);
-
-  return (
-    <DriverWarningContainer p={2} {...props}>
-      <IconContainer hasCircle={hasCircle}>
-        {(supersededBy && <WarningIcon size={20} name="warning" />) ||
-          (supersedes && <Icon size={20} name="info" />)}
-      </IconContainer>
-      <CardContent className="ml2">{warningContent}</CardContent>
-    </DriverWarningContainer>
-  );
-}
-
-DriverWarning.propTypes = propTypes;
-
-export default DriverWarning;
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.stories.tsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.stories.tsx
new file mode 100644
index 00000000000..03e22752acb
--- /dev/null
+++ b/frontend/src/metabase/components/DriverWarning/DriverWarning.stories.tsx
@@ -0,0 +1,37 @@
+import React from "react";
+import { ComponentStory } from "@storybook/react";
+import { createMockDatabase, createMockEngine } from "metabase-types/api/mocks";
+import DriverWarning from "./DriverWarning";
+
+export default {
+  title: "Components/DriverWarning",
+  component: DriverWarning,
+  argTypes: { onChange: { action: "onChange" } },
+};
+
+const Template: ComponentStory<typeof DriverWarning> = args => {
+  return <DriverWarning {...args} />;
+};
+Template.args = {
+  engines: {
+    presto: createMockEngine({
+      "driver-name": "Presto (Deprecated Driver)",
+      "superseded-by": "presto-jdbc",
+    }),
+    "presto-jdbc": createMockEngine({
+      "driver-name": "Presto",
+    }),
+  },
+};
+
+export const New = Template.bind({});
+New.args = {
+  engine: "presto-jdbc",
+  ...Template.args,
+};
+
+export const Deprecated = Template.bind({});
+Deprecated.args = {
+  engine: "presto",
+  ...Template.args,
+};
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.jsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.jsx
deleted file mode 100644
index 65122134563..00000000000
--- a/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import styled from "styled-components";
-
-import { color } from "metabase/lib/colors";
-import { space } from "metabase/styled-components/theme";
-
-import Icon from "metabase/components/Icon";
-
-export const CardContent = styled.div`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
-
-export const IconContainer = styled.div`
-  border-radius: 99px !important;
-  flex-shrink: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: ${props => (props.hasCircle ? "52px" : "32px")};
-  height: ${props => (props.hasCircle ? "52px" : "32px")};
-  background-color: ${props => (props.hasCircle ? "#EEF2F5" : "transparent")};
-`;
-
-export const DriverWarningContainer = styled.div`
-  background-color: #f9fbfb;
-  border-radius: 10px;
-  width: 320px;
-  display: flex;
-  margin-top: 8px;
-  margin-bottom: 8px;
-  margin-left: 26px;
-  padding: 16px;
-`;
-
-export const WarningIcon = styled(Icon)`
-  color: ${color("accent5")};
-`;
-
-export const WarningParagraph = styled.p`
-  margin: ${props => (props.hasMargin ? `${space(1)} 0;` : 0)};
-  color: ${color("text-medium")};
-`;
-
-export const Link = styled.a`
-  color: ${color("brand")};
-  font-weight: 700;
-`;
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.tsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.tsx
new file mode 100644
index 00000000000..88e825d422b
--- /dev/null
+++ b/frontend/src/metabase/components/DriverWarning/DriverWarning.styled.tsx
@@ -0,0 +1,22 @@
+import styled from "styled-components";
+import { color } from "metabase/lib/colors";
+
+export interface WarningRootProps {
+  hasBorder?: boolean;
+}
+
+export const WarningRoot = styled.div<WarningRootProps>`
+  margin-bottom: 2rem;
+  padding: 1rem 0.75rem;
+  color: ${color("text-medium")};
+  border: 1px solid
+    ${props => color(props.hasBorder ? "bg-medium" : "bg-light")};
+  border-radius: 0.5rem;
+  background-color: ${color("bg-light")};
+`;
+
+export const WarningLink = styled.a`
+  color: ${color("brand")};
+  cursor: pointer;
+  font-weight: bold;
+`;
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.tsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.tsx
new file mode 100644
index 00000000000..42572c3c72d
--- /dev/null
+++ b/frontend/src/metabase/components/DriverWarning/DriverWarning.tsx
@@ -0,0 +1,62 @@
+import React from "react";
+import { jt, t } from "ttag";
+import _ from "underscore";
+import { Engine } from "metabase-types/api";
+import { WarningLink, WarningRoot } from "./DriverWarning.styled";
+
+export interface DriverWarningProps {
+  engine?: string;
+  engines: Record<string, Engine>;
+  hasBorder?: boolean;
+  onChange?: (engine: string) => void;
+}
+
+const DriverWarning = ({
+  engine: engineKey,
+  engines,
+  hasBorder,
+  onChange,
+}: DriverWarningProps): JSX.Element | null => {
+  const engine = engineKey ? engines[engineKey] : undefined;
+  const engineName = engine?.["driver-name"];
+
+  const newEngineKey = engine?.["superseded-by"];
+  const newEngine = newEngineKey ? engines[newEngineKey] : undefined;
+  const newEngineName = newEngine?.["driver-name"];
+  const handleChangeToNew = () => newEngineKey && onChange?.(newEngineKey);
+
+  const oldEngineKey = _.findKey(engines, { "superseded-by": engineKey });
+  const oldEngine = oldEngineKey ? engines[oldEngineKey] : undefined;
+  const handleChangeToOld = () => oldEngineKey && onChange?.(oldEngineKey);
+
+  if (newEngine) {
+    return (
+      <WarningRoot hasBorder={hasBorder}>
+        {t`This driver will be removed in a future release.`}{" "}
+        {jt`We recommend you upgrade to the ${(
+          <WarningLink key="link" onClick={handleChangeToNew}>
+            {t`new ${newEngineName} driver`}
+          </WarningLink>
+        )}.`}
+      </WarningRoot>
+    );
+  }
+
+  if (oldEngine) {
+    return (
+      <WarningRoot>
+        {t`This is our new ${engineName} driver.`}{" "}
+        {t`The old driver has been deprecated and will be removed in a future release.`}{" "}
+        {jt`If you really need to use it, you can ${(
+          <WarningLink key="link" onClick={handleChangeToOld}>
+            {t`find it here`}
+          </WarningLink>
+        )}.`}
+      </WarningRoot>
+    );
+  }
+
+  return null;
+};
+
+export default DriverWarning;
diff --git a/frontend/src/metabase/components/DriverWarning/DriverWarning.unit.spec.tsx b/frontend/src/metabase/components/DriverWarning/DriverWarning.unit.spec.tsx
new file mode 100644
index 00000000000..addf223a0e5
--- /dev/null
+++ b/frontend/src/metabase/components/DriverWarning/DriverWarning.unit.spec.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import { createMockEngine } from "metabase-types/api/mocks";
+import DriverWarning from "./DriverWarning";
+
+describe("DriverWarning", () => {
+  const engines = {
+    postgres: createMockEngine({
+      "driver-name": "PostgreSQL",
+    }),
+    presto: createMockEngine({
+      "driver-name": "Presto (Deprecated Driver)",
+      "superseded-by": "presto-jdbc",
+    }),
+    "presto-jdbc": createMockEngine({
+      "driver-name": "Presto",
+    }),
+  };
+
+  it("should render a warning when the driver is deprecated", () => {
+    render(<DriverWarning engine="presto" engines={engines} />);
+    expect(screen.getByText(/This driver will be removed/)).toBeInTheDocument();
+  });
+
+  it("should render a warning when the driver is new", () => {
+    render(<DriverWarning engine="presto-jdbc" engines={engines} />);
+    expect(screen.getByText(/This is our new Presto/)).toBeInTheDocument();
+  });
+
+  it("should render nothing when the driver does not exist", () => {
+    render(<DriverWarning engine="invalid" engines={engines} />);
+    expect(screen.queryByText(/driver/)).not.toBeInTheDocument();
+  });
+
+  it("should render nothing when there is no new driver", () => {
+    render(<DriverWarning engine="postgres" engines={engines} />);
+    expect(screen.queryByText(/driver/)).not.toBeInTheDocument();
+  });
+});
diff --git a/frontend/src/metabase/components/DriverWarning/index.js b/frontend/src/metabase/components/DriverWarning/index.ts
similarity index 100%
rename from frontend/src/metabase/components/DriverWarning/index.js
rename to frontend/src/metabase/components/DriverWarning/index.ts
diff --git a/frontend/src/metabase/containers/DriverWarning/DriverWarning.tsx b/frontend/src/metabase/containers/DriverWarning/DriverWarning.tsx
new file mode 100644
index 00000000000..0fda06fa8fe
--- /dev/null
+++ b/frontend/src/metabase/containers/DriverWarning/DriverWarning.tsx
@@ -0,0 +1,25 @@
+import { connect } from "react-redux";
+import DriverWarning from "metabase/components/DriverWarning";
+import { Engine } from "metabase-types/api";
+import { State } from "metabase-types/store";
+
+export interface DriverWarningProps {
+  engine?: string;
+  hasBorder?: boolean;
+  onChange?: (engine: string) => void;
+}
+
+interface DriverWarningStateProps {
+  engines: Record<string, Engine>;
+}
+
+const mapStateToProps = (state: State) => ({
+  engines: state.settings.values.engines,
+});
+
+export default connect<
+  DriverWarningStateProps,
+  unknown,
+  DriverWarningProps,
+  State
+>(mapStateToProps)(DriverWarning);
diff --git a/frontend/src/metabase/containers/DriverWarning/index.ts b/frontend/src/metabase/containers/DriverWarning/index.ts
new file mode 100644
index 00000000000..80816f2cd18
--- /dev/null
+++ b/frontend/src/metabase/containers/DriverWarning/index.ts
@@ -0,0 +1 @@
+export { default } from "./DriverWarning";
diff --git a/frontend/src/metabase/css/admin.css b/frontend/src/metabase/css/admin.css
index eaa724c3dc7..dd5de259ffb 100644
--- a/frontend/src/metabase/css/admin.css
+++ b/frontend/src/metabase/css/admin.css
@@ -159,7 +159,7 @@
 
 .AdminSelect {
   display: inline-block;
-  padding: 0.6em;
+  padding: 0.6em 0.9em;
   border: 1px solid var(--color-border);
   background-color: var(--color-bg-white);
   border-radius: var(--default-border-radius);
diff --git a/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.tsx b/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.tsx
index 2ba4d07c2e9..a6c8a25b543 100644
--- a/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.tsx
+++ b/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.tsx
@@ -1,8 +1,10 @@
 import React, { useEffect } from "react";
 import { t } from "ttag";
+import _ from "underscore";
 import { updateIn } from "icepick";
 import Users from "metabase/entities/users";
 import Databases from "metabase/entities/databases";
+import DriverWarning from "metabase/containers/DriverWarning";
 import ActiveStep from "../ActiveStep";
 import InactiveStep from "../InvactiveStep";
 import SetupSection from "../SetupSection";
@@ -121,9 +123,22 @@ const DatabaseForm = ({
       database={database}
       onSubmit={handleSubmit}
     >
-      {({ formFields, Form, FormField, FormFooter }: FormProps) => (
+      {({
+        Form,
+        FormField,
+        FormFooter,
+        formFields,
+        values,
+        onChangeField,
+      }: FormProps) => (
         <Form>
-          {formFields.map(({ name }) => (
+          <FormField name="engine" />
+          <DriverWarning
+            engine={values.engine}
+            hasBorder={true}
+            onChange={engine => onChangeField("engine", engine)}
+          />
+          {_.reject(formFields, { name: "engine" }).map(({ name }) => (
             <FormField key={name} name={name} />
           ))}
           {engine && <FormFooter submitTitle={t`Next`} />}
diff --git a/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.unit.spec.tsx b/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.unit.spec.tsx
index bea62f1403c..2c585f5665b 100644
--- a/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.unit.spec.tsx
+++ b/frontend/src/metabase/setup/components/DatabaseStep/DatabaseStep.unit.spec.tsx
@@ -3,18 +3,20 @@ import { render, screen } from "@testing-library/react";
 import DatabaseStep, { DatabaseStepProps } from "./DatabaseStep";
 import { DatabaseDetails, DatabaseInfo } from "../../types";
 
-const FormMock = () => <div />;
+const ComponentMock = () => <div />;
 
 jest.mock("metabase/entities/databases", () => ({
   forms: { setup: jest.fn() },
-  Form: FormMock,
+  Form: ComponentMock,
 }));
 
 jest.mock("metabase/entities/users", () => ({
   forms: { setup_invite: jest.fn() },
-  Form: FormMock,
+  Form: ComponentMock,
 }));
 
+jest.mock("metabase/containers/DriverWarning", () => ComponentMock);
+
 describe("DatabaseStep", () => {
   it("should render in active state", () => {
     const props = getProps({
diff --git a/frontend/src/metabase/setup/components/DatabaseStep/types.ts b/frontend/src/metabase/setup/components/DatabaseStep/types.ts
index 4d77623ea7a..1edddc1c2dc 100644
--- a/frontend/src/metabase/setup/components/DatabaseStep/types.ts
+++ b/frontend/src/metabase/setup/components/DatabaseStep/types.ts
@@ -5,10 +5,16 @@ export interface FormField {
 }
 
 export interface FormProps {
-  formFields: FormField[];
   Form: ComponentType;
   FormField: ComponentType<FormFieldProps>;
   FormFooter: ComponentType<FormFooterProps>;
+  formFields: FormField[];
+  values: FormValues;
+  onChangeField: (field: string, value: unknown) => void;
+}
+
+export interface FormValues {
+  engine?: string;
 }
 
 export interface FormFieldProps {
diff --git a/frontend/test/metabase/scenarios/admin/databases/add-presto.cy.spec.js b/frontend/test/metabase/scenarios/admin/databases/add-presto.cy.spec.js
index a0e92c7ccb0..6a9238ab266 100644
--- a/frontend/test/metabase/scenarios/admin/databases/add-presto.cy.spec.js
+++ b/frontend/test/metabase/scenarios/admin/databases/add-presto.cy.spec.js
@@ -62,9 +62,7 @@ describe("admin > database > add > Presto", () => {
     cy.findByText("Need help setting up your database?");
     cy.findByRole("link", { name: "Our docs can help." });
 
-    cy.findByText(
-      "This is our new Presto driver, which is faster and more reliable.",
-    );
+    cy.contains("This is our new Presto driver.");
 
     // Switch to the deprecated old Presto driver
     cy.contains(
@@ -110,14 +108,10 @@ describe("admin > database > add > Presto", () => {
       "",
     );
 
-    cy.findByText(
-      "This driver has been deprecated and will be removed in a future release.",
-    );
+    cy.contains("This driver will be removed in a future release. ");
 
     // Switch back to the new Presto driver
-    cy.contains(
-      "We recommend that you upgrade to the new Presto driver, which is faster and more reliable.",
-    )
+    cy.contains("We recommend you upgrade to the new Presto driver.")
       .find("a")
       .click();
 
diff --git a/frontend/test/metabase/scenarios/admin/databases/add.cy.spec.js b/frontend/test/metabase/scenarios/admin/databases/add.cy.spec.js
index c9d1829f639..4f23d9d1797 100644
--- a/frontend/test/metabase/scenarios/admin/databases/add.cy.spec.js
+++ b/frontend/test/metabase/scenarios/admin/databases/add.cy.spec.js
@@ -298,7 +298,7 @@ describe("scenarios > admin > databases > add", () => {
       cy.findByText("find it here").click();
       cy.findByText("BigQuery (Deprecated Driver)");
       cy.findByText("Need help setting up your database?").should("not.exist");
-      cy.findByText("This driver has been deprecated", { exact: false });
+      cy.findByText("This driver will be removed", { exact: false });
     });
   });
 
-- 
GitLab