diff --git a/frontend/src/metabase/entities/tables.js b/frontend/src/metabase/entities/tables.js
index fb6589cdaf712718a519a54ae3a04bbec524fd34..dbb472a252f3fa152234a31a1015742d7626d9b0 100644
--- a/frontend/src/metabase/entities/tables.js
+++ b/frontend/src/metabase/entities/tables.js
@@ -21,7 +21,7 @@ import Metrics from "metabase/entities/metrics";
 import Segments from "metabase/entities/segments";
 import Questions from "metabase/entities/questions";
 
-import { GET, PUT } from "metabase/lib/api";
+import { PUT } from "metabase/lib/api";
 import {
   getMetadata,
   getMetadataUnfiltered,
@@ -31,11 +31,9 @@ import {
   getQuestionVirtualTableId,
 } from "metabase-lib/metadata/utils/saved-questions";
 
-const listTables = GET("/api/table");
 const listTablesForDatabase = async (...args) =>
   // HACK: no /api/database/:dbId/tables endpoint
-  (await GET("/api/database/:dbId/metadata")(...args)).tables;
-const listTablesForSchema = GET("/api/database/:dbId/schema/:schemaName");
+  (await MetabaseApi.db_metadata(...args)).tables;
 const updateFieldOrder = PUT("/api/table/:id/fields/order");
 const updateTables = PUT("/api/table");
 
@@ -57,11 +55,11 @@ const Tables = createEntity({
   api: {
     list: async (params, ...args) => {
       if (params.dbId != null && params.schemaName != null) {
-        return listTablesForSchema(params, ...args);
+        return MetabaseApi.db_schema_tables(params, ...args);
       } else if (params.dbId != null) {
         return listTablesForDatabase(params, ...args);
       } else {
-        return listTables(params, ...args);
+        return MetabaseApi.table_list(params, ...args);
       }
     },
   },
diff --git a/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.tsx b/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.tsx
index 39878d961938eb284c94ecfdfd67353665096294..a6e64d1a2b1578284ff54b4eb600ad3d374bd839 100644
--- a/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.tsx
+++ b/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.tsx
@@ -2,6 +2,7 @@ import { useMemo } from "react";
 import { ngettext, msgid } from "ttag";
 import _ from "underscore";
 
+import { SearchResult } from "metabase-types/api";
 import Search from "metabase/entities/search";
 import SidebarContent from "metabase/query_builder/components/SidebarContent";
 import type { State } from "metabase-types/store";
@@ -18,15 +19,15 @@ import {
 } from "./NodeList.styled";
 import { PaneContent } from "./Pane.styled";
 
-interface DatabaseTablesPaneProps {
+export interface DatabaseTablesPaneProps {
   onBack: () => void;
   onClose: () => void;
   onItemClick: (type: string, item: unknown) => void;
   database: Database;
-  searchResults: any[]; // TODO: /api/search is yet to be typed
+  searchResults: SearchResult[];
 }
 
-const DatabaseTablesPane = ({
+export const DatabaseTablesPane = ({
   database,
   onItemClick,
   searchResults,
@@ -97,7 +98,10 @@ const DatabaseTablesPane = ({
           <ul>
             {tables.map(table => (
               <li key={table.id}>
-                <NodeListItemLink onClick={() => onItemClick("table", table)}>
+                <NodeListItemLink
+                  disabled={table.initial_sync_status !== "complete"}
+                  onClick={() => onItemClick("table", table)}
+                >
                   <NodeListItemIcon name="table" />
                   <NodeListItemName>{table.table_name}</NodeListItemName>
                 </NodeListItemLink>
diff --git a/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.unit.spec.tsx b/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.unit.spec.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d75555b6f65507ef162ad3957e86a5db7e1ac9eb
--- /dev/null
+++ b/frontend/src/metabase/query_builder/components/dataref/DatabaseTablesPane.unit.spec.tsx
@@ -0,0 +1,119 @@
+import userEvent from "@testing-library/user-event";
+
+import { createMockMetadata } from "__support__/metadata";
+import { renderWithProviders, screen } from "__support__/ui";
+import { getNextId } from "__support__/utils";
+import {
+  createMockDatabase,
+  createMockSearchResult,
+} from "metabase-types/api/mocks";
+import { checkNotNull } from "metabase/core/utils/types";
+
+import type { DatabaseTablesPaneProps } from "./DatabaseTablesPane";
+import { DatabaseTablesPane } from "./DatabaseTablesPane";
+
+const database = createMockDatabase();
+
+const metadata = createMockMetadata({
+  databases: [database],
+});
+
+const incompleteTableSearchResult = createMockSearchResult({
+  id: getNextId(),
+  table_name: "Incomplete result",
+  model: "table",
+  initial_sync_status: "incomplete",
+});
+
+const abortedTableSearchResult = createMockSearchResult({
+  id: getNextId(),
+  table_name: "Aborted result",
+  model: "table",
+  initial_sync_status: "aborted",
+});
+
+const completeTableSearchResult = createMockSearchResult({
+  id: getNextId(),
+  table_name: "Complete result",
+  model: "table",
+  initial_sync_status: "complete",
+});
+
+const defaultProps = {
+  database: checkNotNull(metadata.database(database.id)),
+  searchResults: [],
+  onBack: jest.fn(),
+  onClose: jest.fn(),
+  onItemClick: jest.fn(),
+};
+
+const setup = (options?: Partial<DatabaseTablesPaneProps>) => {
+  return renderWithProviders(
+    <DatabaseTablesPane {...defaultProps} {...options} />,
+  );
+};
+
+describe("DatabaseTablesPane", () => {
+  it("should show tables with initial_sync_status='incomplete' as non-interactive (disabled)", () => {
+    setup({
+      searchResults: [incompleteTableSearchResult],
+    });
+
+    const textElement = screen.getByText(
+      checkNotNull(incompleteTableSearchResult.table_name),
+    );
+
+    expect(textElement).toBeInTheDocument();
+    expectToBeDisabled(textElement);
+  });
+
+  it("should show tables with initial_sync_status='aborted' as non-interactive (disabled)", () => {
+    setup({
+      searchResults: [abortedTableSearchResult],
+    });
+
+    const textElement = screen.getByText(
+      checkNotNull(abortedTableSearchResult.table_name),
+    );
+
+    expect(textElement).toBeInTheDocument();
+    expectToBeDisabled(textElement);
+  });
+
+  it("should show tables with initial_sync_status='complete' as interactive (enabled)", () => {
+    setup({
+      searchResults: [completeTableSearchResult],
+    });
+
+    const textElement = screen.getByText(
+      checkNotNull(completeTableSearchResult.table_name),
+    );
+
+    expect(textElement).toBeInTheDocument();
+    expectToBeEnabled(textElement);
+  });
+});
+
+/**
+ * We're dealing with <a> here, which are presented as disabled thanks to:
+ * - not having "href" attribute
+ * - using "pointer-events: none"
+ *
+ * Due to this "expect().toBeDisabled()" and "expect().toBeEnabled()" won't work as expected.
+ *
+ * Clicking the element allows us to detect interactiveness (being enabled/disabled) with certainty.
+ */
+function expectToBeDisabled(element: Element) {
+  expect(() => {
+    userEvent.click(element);
+  }).toThrow();
+}
+
+/**
+ * @see expectToBeDisabled
+ */
+function expectToBeEnabled(element: Element) {
+  expect(() => {
+    userEvent.click(element);
+  }).not.toThrow();
+}
diff --git a/frontend/src/metabase/query_builder/components/dataref/NodeList.styled.tsx b/frontend/src/metabase/query_builder/components/dataref/NodeList.styled.tsx
index 4ea69e64f3960317fe44820923bac3bd66de0a07..fafe5010cbd7169ddecdd5bc3aadbed0d2b22dac 100644
--- a/frontend/src/metabase/query_builder/components/dataref/NodeList.styled.tsx
+++ b/frontend/src/metabase/query_builder/components/dataref/NodeList.styled.tsx
@@ -1,3 +1,4 @@
+import { css } from "@emotion/react";
 import styled from "@emotion/styled";
 
 import { Icon } from "metabase/core/components/Icon";
@@ -20,7 +21,11 @@ export const NodeListItemIcon = styled(Icon)`
   width: ${space(2)};
 `;
 
-export const NodeListItemLink = styled.a`
+interface NodeListItemLinkProps {
+  disabled?: boolean;
+}
+
+export const NodeListItemLink = styled.a<NodeListItemLinkProps>`
   border-radius: 8px;
   display: flex;
   align-items: center;
@@ -35,6 +40,18 @@ export const NodeListItemLink = styled.a`
   :hover {
     background-color: ${color("bg-medium")};
   }
+
+  ${props =>
+    props.disabled &&
+    css`
+      pointer-events: none;
+      opacity: 0.4;
+      color: inherit;
+
+      ${NodeListItemIcon} {
+        color: inherit;
+      }
+    `};
 `;
 
 export const NodeListContainer = styled.ul`