From 0ef26e645ce137c69cc424f128a6627d27225850 Mon Sep 17 00:00:00 2001
From: Anton Kulyk <kuliks.anton@gmail.com>
Date: Thu, 17 Aug 2023 13:16:48 +0100
Subject: [PATCH] Convert native QB actions to TypeScript (#33234)

---
 .../actions/{native.js => native.ts}          | 128 +++++++++++-------
 1 file changed, 76 insertions(+), 52 deletions(-)
 rename frontend/src/metabase/query_builder/actions/{native.js => native.ts} (58%)

diff --git a/frontend/src/metabase/query_builder/actions/native.js b/frontend/src/metabase/query_builder/actions/native.ts
similarity index 58%
rename from frontend/src/metabase/query_builder/actions/native.js
rename to frontend/src/metabase/query_builder/actions/native.ts
index f9ad1291e56..2f66e524151 100644
--- a/frontend/src/metabase/query_builder/actions/native.js
+++ b/frontend/src/metabase/query_builder/actions/native.ts
@@ -5,6 +5,17 @@ import { createThunkAction } from "metabase/lib/redux";
 
 import Questions from "metabase/entities/questions";
 import { getMetadata } from "metabase/selectors/metadata";
+
+import type {
+  CardId,
+  NativeQuerySnippet,
+  Parameter,
+  TemplateTag,
+} from "metabase-types/api";
+import type { Dispatch, GetState } from "metabase-types/store";
+
+import type NativeQuery from "metabase-lib/queries/NativeQuery";
+
 import {
   getDataReferenceStack,
   getNativeEditorCursorOffset,
@@ -27,7 +38,7 @@ export const setDataReferenceStack = createAction(SET_DATA_REFERENCE_STACK);
 export const POP_DATA_REFERENCE_STACK = "metabase/qb/POP_DATA_REFERENCE_STACK";
 export const popDataReferenceStack = createThunkAction(
   POP_DATA_REFERENCE_STACK,
-  () => (dispatch, getState) => {
+  () => (dispatch: Dispatch, getState: GetState) => {
     const stack = getDataReferenceStack(getState());
     dispatch(setDataReferenceStack(stack.slice(0, -1)));
   },
@@ -37,17 +48,18 @@ export const PUSH_DATA_REFERENCE_STACK =
   "metabase/qb/PUSH_DATA_REFERENCE_STACK";
 export const pushDataReferenceStack = createThunkAction(
   PUSH_DATA_REFERENCE_STACK,
-  item => (dispatch, getState) => {
-    const stack = getDataReferenceStack(getState());
-    dispatch(setDataReferenceStack(stack.concat([item])));
-  },
+  (item: { type: string; item: unknown }) =>
+    (dispatch: Dispatch, getState: GetState) => {
+      const stack = getDataReferenceStack(getState());
+      dispatch(setDataReferenceStack(stack.concat([item])));
+    },
 );
 
 export const OPEN_DATA_REFERENCE_AT_QUESTION =
   "metabase/qb/OPEN_DATA_REFERENCE_AT_QUESTION";
 export const openDataReferenceAtQuestion = createThunkAction(
   OPEN_DATA_REFERENCE_AT_QUESTION,
-  id => async (dispatch, getState) => {
+  (id: CardId) => async (dispatch: Dispatch, getState: GetState) => {
     const action = await dispatch(
       Questions.actions.fetch(
         { id },
@@ -79,7 +91,9 @@ export const toggleTemplateTagsEditor = createAction(
 
 export const SET_IS_SHOWING_TEMPLATE_TAGS_EDITOR =
   "metabase/qb/SET_IS_SHOWING_TEMPLATE_TAGS_EDITOR";
-export const setIsShowingTemplateTagsEditor = isShowingTemplateTagsEditor => ({
+export const setIsShowingTemplateTagsEditor = (
+  isShowingTemplateTagsEditor: boolean,
+) => ({
   type: SET_IS_SHOWING_TEMPLATE_TAGS_EDITOR,
   isShowingTemplateTagsEditor,
 });
@@ -91,12 +105,14 @@ export const toggleSnippetSidebar = createAction(TOGGLE_SNIPPET_SIDEBAR, () => {
 
 export const SET_IS_SHOWING_SNIPPET_SIDEBAR =
   "metabase/qb/SET_IS_SHOWING_SNIPPET_SIDEBAR";
-export const setIsShowingSnippetSidebar = isShowingSnippetSidebar => ({
+export const setIsShowingSnippetSidebar = (
+  isShowingSnippetSidebar: boolean,
+) => ({
   type: SET_IS_SHOWING_SNIPPET_SIDEBAR,
   isShowingSnippetSidebar,
 });
 
-export const setIsNativeEditorOpen = isNativeEditorOpen => ({
+export const setIsNativeEditorOpen = (isNativeEditorOpen: boolean) => ({
   type: SET_UI_CONTROLS,
   payload: { isNativeEditorOpen },
 });
@@ -114,60 +130,68 @@ export const SET_SNIPPET_COLLECTION_ID =
   "metabase/qb/SET_SNIPPET_COLLECTION_ID";
 export const setSnippetCollectionId = createAction(SET_SNIPPET_COLLECTION_ID);
 
-export const openSnippetModalWithSelectedText = () => (dispatch, getState) => {
-  const state = getState();
-  const content = getNativeEditorSelectedText(state);
-  const collection_id = getSnippetCollectionId(state);
-  dispatch(setModalSnippet({ content, collection_id }));
-};
+export const openSnippetModalWithSelectedText =
+  () => (dispatch: Dispatch, getState: GetState) => {
+    const state = getState();
+    const content = getNativeEditorSelectedText(state);
+    const collection_id = getSnippetCollectionId(state);
+    dispatch(setModalSnippet({ content, collection_id }));
+  };
 
-export const closeSnippetModal = () => dispatch => {
+export const closeSnippetModal = () => (dispatch: Dispatch) => {
   dispatch(setModalSnippet(null));
 };
 
-export const insertSnippet = snip => (dispatch, getState) => {
-  const name = snip.name;
-  const question = getQuestion(getState());
-  const query = question.query();
-  const nativeEditorCursorOffset = getNativeEditorCursorOffset(getState());
-  const nativeEditorSelectedText = getNativeEditorSelectedText(getState());
-  const selectionStart =
-    nativeEditorCursorOffset - (nativeEditorSelectedText || "").length;
-  const newText =
-    query.queryText().slice(0, selectionStart) +
-    `{{snippet: ${name}}}` +
-    query.queryText().slice(nativeEditorCursorOffset);
-  const datasetQuery = query
-    .setQueryText(newText)
-    .updateSnippetsWithIds([snip])
-    .datasetQuery();
-  dispatch(updateQuestion(question.setDatasetQuery(datasetQuery)));
-};
-
-export const SET_TEMPLATE_TAG = "metabase/qb/SET_TEMPLATE_TAG";
-export const setTemplateTag = createThunkAction(SET_TEMPLATE_TAG, tag => {
-  return (dispatch, getState) => {
+export const insertSnippet =
+  (snippet: NativeQuerySnippet) => (dispatch: Dispatch, getState: GetState) => {
+    const name = snippet.name;
     const question = getQuestion(getState());
-    const newQuestion = question
-      .query()
-      .setTemplateTag(tag.name, tag)
-      .question();
-
-    dispatch(updateQuestion(newQuestion));
+    if (!question) {
+      return;
+    }
+    const query = question.query() as NativeQuery;
+    const nativeEditorCursorOffset = getNativeEditorCursorOffset(getState());
+    const nativeEditorSelectedText = getNativeEditorSelectedText(getState());
+    const selectionStart =
+      nativeEditorCursorOffset - (nativeEditorSelectedText || "").length;
+    const newText =
+      query.queryText().slice(0, selectionStart) +
+      `{{snippet: ${name}}}` +
+      query.queryText().slice(nativeEditorCursorOffset);
+    const datasetQuery = query
+      .setQueryText(newText)
+      .updateSnippetsWithIds([snippet])
+      .datasetQuery();
+    dispatch(updateQuestion(question.setDatasetQuery(datasetQuery)));
   };
-});
+
+export const SET_TEMPLATE_TAG = "metabase/qb/SET_TEMPLATE_TAG";
+export const setTemplateTag = createThunkAction(
+  SET_TEMPLATE_TAG,
+  (tag: TemplateTag) => {
+    return (dispatch: Dispatch, getState: GetState) => {
+      const question = getQuestion(getState());
+      if (!question) {
+        return;
+      }
+      const query = question.query() as NativeQuery;
+      const newQuestion = query.setTemplateTag(tag.name, tag).question();
+      dispatch(updateQuestion(newQuestion));
+    };
+  },
+);
 
 export const SET_TEMPLATE_TAG_CONFIG = "metabase/qb/SET_TEMPLATE_TAG_CONFIG";
 export const setTemplateTagConfig = createThunkAction(
   SET_TEMPLATE_TAG_CONFIG,
-  (tag, parameter) => {
-    return (dispatch, getState) => {
+  (tag: TemplateTag, parameter: Parameter) => {
+    return (dispatch: Dispatch, getState: GetState) => {
       const question = getQuestion(getState());
-      const newQuestion = question
-        .query()
-        .setTemplateTagConfig(tag, parameter)
-        .question();
-
+      if (!question) {
+        return;
+      }
+      const query = question.query() as NativeQuery;
+      const newQuestion = query.setTemplateTagConfig(tag, parameter).question();
       dispatch(updateQuestion(newQuestion));
     };
   },
-- 
GitLab