This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch 4.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 21cb4a90bbfb8775cc51cfb2c4f9394775658422
Author: JUST.in DO IT <[email protected]>
AuthorDate: Fri Jun 14 09:35:17 2024 -0700

    chore(sqllab): Add logging for actions (#28876)
    
    (cherry picked from commit 05829cbda983dde69d4cf1cbd0517cff0ec8d104)
---
 .../src/SqlLab/components/ResultSet/index.tsx      | 19 +++++++-
 .../components/RunQueryActionButton/index.tsx      | 14 +++++-
 .../src/SqlLab/components/SaveQuery/index.tsx      | 14 +++++-
 .../SqlLab/components/ShareSqlLabQuery/index.tsx   |  7 ++-
 .../src/SqlLab/components/SqlEditor/index.tsx      | 52 +++++++++++++++++---
 .../SqlLab/components/TabbedSqlEditors/index.tsx   | 12 ++++-
 superset-frontend/src/logger/LogUtils.ts           | 16 +++++++
 superset-frontend/src/logger/useLogAction.test.ts  | 55 ++++++++++++++++++++++
 superset-frontend/src/logger/useLogAction.ts       | 40 ++++++++++++++++
 9 files changed, 217 insertions(+), 12 deletions(-)

diff --git a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx 
b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
index 87ba0370ed..830ed3b9c2 100644
--- a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
+++ b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
@@ -62,6 +62,12 @@ import {
   reRunQuery,
 } from 'src/SqlLab/actions/sqlLab';
 import { URL_PARAMS } from 'src/constants';
+import useLogAction from 'src/logger/useLogAction';
+import {
+  LOG_ACTIONS_SQLLAB_COPY_RESULT_TO_CLIPBOARD,
+  LOG_ACTIONS_SQLLAB_CREATE_CHART,
+  LOG_ACTIONS_SQLLAB_DOWNLOAD_CSV,
+} from 'src/logger/LogUtils';
 import Icons from 'src/components/Icons';
 import ExploreCtasResultsButton from '../ExploreCtasResultsButton';
 import ExploreResultsButton from '../ExploreResultsButton';
@@ -162,6 +168,7 @@ const ResultSet = ({
         'dbId',
         'tab',
         'sql',
+        'sqlEditorId',
         'templateParams',
         'schema',
         'rows',
@@ -192,6 +199,7 @@ const ResultSet = ({
 
   const history = useHistory();
   const dispatch = useDispatch();
+  const logAction = useLogAction({ queryId, sqlEditorId: query.sqlEditorId });
 
   const reRunQueryIfSessionTimeoutErrorOnMount = useCallback(() => {
     if (
@@ -249,7 +257,7 @@ const ResultSet = ({
     const { results } = query;
 
     const openInNewWindow = clickEvent.metaKey;
-
+    logAction(LOG_ACTIONS_SQLLAB_CREATE_CHART, {});
     if (results?.query_id) {
       const key = await postFormData(results.query_id, 'query', {
         ...EXPLORE_CHART_DEFAULT,
@@ -312,7 +320,11 @@ const ResultSet = ({
               />
             )}
             {csv && (
-              <Button buttonSize="small" href={getExportCsvUrl(query.id)}>
+              <Button
+                buttonSize="small"
+                href={getExportCsvUrl(query.id)}
+                onClick={() => logAction(LOG_ACTIONS_SQLLAB_DOWNLOAD_CSV, {})}
+              >
                 <i className="fa fa-file-text-o" /> {t('Download to CSV')}
               </Button>
             )}
@@ -326,6 +338,9 @@ const ResultSet = ({
                 </Button>
               }
               hideTooltip
+              onCopyEnd={() =>
+                logAction(LOG_ACTIONS_SQLLAB_COPY_RESULT_TO_CLIPBOARD, {})
+              }
             />
           </ResultSetButtons>
           {search && (
diff --git 
a/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx 
b/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
index 30f8121132..0d1740cbac 100644
--- a/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
+++ b/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx
@@ -25,6 +25,11 @@ import { DropdownButton } from 
'src/components/DropdownButton';
 import { detectOS } from 'src/utils/common';
 import { QueryButtonProps } from 'src/SqlLab/types';
 import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
+import {
+  LOG_ACTIONS_SQLLAB_RUN_QUERY,
+  LOG_ACTIONS_SQLLAB_STOP_QUERY,
+} from 'src/logger/LogUtils';
+import useLogAction from 'src/logger/useLogAction';
 
 export interface RunQueryActionButtonProps {
   queryEditorId: string;
@@ -57,7 +62,13 @@ const onClick = (
   allowAsync: boolean,
   runQuery: (c?: boolean) => void = () => undefined,
   stopQuery = () => {},
+  logAction: (name: string, payload: Record<string, any>) => void,
 ): void => {
+  const eventName = shouldShowStopButton
+    ? LOG_ACTIONS_SQLLAB_STOP_QUERY
+    : LOG_ACTIONS_SQLLAB_RUN_QUERY;
+
+  logAction(eventName, { shortcut: false });
   if (shouldShowStopButton) return stopQuery();
   if (allowAsync) {
     return runQuery(true);
@@ -89,6 +100,7 @@ const RunQueryActionButton = ({
   stopQuery,
 }: RunQueryActionButtonProps) => {
   const theme = useTheme();
+  const logAction = useLogAction({ queryEditorId });
   const userOS = detectOS();
 
   const { selectedText, sql } = useQueryEditor(queryEditorId, [
@@ -121,7 +133,7 @@ const RunQueryActionButton = ({
       <ButtonComponent
         data-test="run-query-action"
         onClick={() =>
-          onClick(shouldShowStopBtn, allowAsync, runQuery, stopQuery)
+          onClick(shouldShowStopBtn, allowAsync, runQuery, stopQuery, 
logAction)
         }
         disabled={isDisabled}
         tooltip={
diff --git a/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx 
b/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
index a7ac8b1b2a..766c37cfbd 100644
--- a/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SaveQuery/index.tsx
@@ -33,6 +33,11 @@ import {
 import { getDatasourceAsSaveableDataset } from 'src/utils/datasourceUtils';
 import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
 import { QueryEditor } from 'src/SqlLab/types';
+import useLogAction from 'src/logger/useLogAction';
+import {
+  LOG_ACTIONS_SQLLAB_CREATE_CHART,
+  LOG_ACTIONS_SQLLAB_SAVE_QUERY,
+} from 'src/logger/LogUtils';
 
 interface SaveQueryProps {
   queryEditorId: string;
@@ -90,6 +95,7 @@ const SaveQuery = ({
     }),
     [queryEditor, columns],
   );
+  const logAction = useLogAction({ queryEditorId });
   const defaultLabel = query.name || query.description || t('Undefined');
   const [description, setDescription] = useState<string>(
     query.description || '',
@@ -104,7 +110,12 @@ const SaveQuery = ({
 
   const overlayMenu = (
     <Menu>
-      <Menu.Item onClick={() => setShowSaveDatasetModal(true)}>
+      <Menu.Item
+        onClick={() => {
+          logAction(LOG_ACTIONS_SQLLAB_CREATE_CHART, {});
+          setShowSaveDatasetModal(true);
+        }}
+      >
         {t('Save dataset')}
       </Menu.Item>
     </Menu>
@@ -127,6 +138,7 @@ const SaveQuery = ({
   const close = () => setShowSave(false);
 
   const onSaveWrapper = () => {
+    logAction(LOG_ACTIONS_SQLLAB_SAVE_QUERY, {});
     onSave(queryPayload(), query.id);
     close();
   };
diff --git a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx 
b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
index 8f4cde1a66..b0a63f56e0 100644
--- a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
+++ b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/index.tsx
@@ -31,6 +31,8 @@ import CopyToClipboard from 'src/components/CopyToClipboard';
 import { storeQuery } from 'src/utils/common';
 import { getClientErrorObject } from 'src/utils/getClientErrorObject';
 import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
+import { LOG_ACTIONS_SQLLAB_COPY_LINK } from 'src/logger/LogUtils';
+import useLogAction from 'src/logger/useLogAction';
 
 interface ShareSqlLabQueryProps {
   queryEditorId: string;
@@ -52,7 +54,7 @@ const ShareSqlLabQuery = ({
   addDangerToast,
 }: ShareSqlLabQueryProps) => {
   const theme = useTheme();
-
+  const logAction = useLogAction({ queryEditorId });
   const { dbId, name, schema, autorun, sql, remoteId, templateParams } =
     useQueryEditor(queryEditorId, [
       'dbId',
@@ -92,6 +94,9 @@ const ShareSqlLabQuery = ({
     }
   };
   const getCopyUrl = (callback: Function) => {
+    logAction(LOG_ACTIONS_SQLLAB_COPY_LINK, {
+      shortcut: false,
+    });
     if (isFeatureEnabled(FeatureFlag.ShareQueriesViaKvStore)) {
       return getCopyUrlForKvStore(callback);
     }
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx 
b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
index 1590726953..0bf256b3a3 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
@@ -98,6 +98,17 @@ import {
 } from 'src/utils/localStorageHelpers';
 import { EmptyStateBig } from 'src/components/EmptyState';
 import getBootstrapData from 'src/utils/getBootstrapData';
+import useLogAction from 'src/logger/useLogAction';
+import {
+  LOG_ACTIONS_SQLLAB_CREATE_TABLE_AS,
+  LOG_ACTIONS_SQLLAB_CREATE_VIEW_AS,
+  LOG_ACTIONS_SQLLAB_ESTIMATE_QUERY_COST,
+  LOG_ACTIONS_SQLLAB_FORMAT_SQL,
+  LOG_ACTIONS_SQLLAB_LOAD_TAB_STATE,
+  LOG_ACTIONS_SQLLAB_RUN_QUERY,
+  LOG_ACTIONS_SQLLAB_STOP_QUERY,
+  Logger,
+} from 'src/logger/LogUtils';
 import TemplateParamsEditor from '../TemplateParamsEditor';
 import SouthPane from '../SouthPane';
 import SaveQuery, { QueryPayload } from '../SaveQuery';
@@ -271,6 +282,7 @@ const SqlEditor: React.FC<Props> = ({
       };
     }, shallowEqual);
 
+  const logAction = useLogAction({ queryEditorId: queryEditor.id });
   const isActive = currentQueryEditorId === queryEditor.id;
   const [height, setHeight] = useState(0);
   const [autorun, setAutorun] = useState(queryEditor.autorun);
@@ -314,9 +326,15 @@ const SqlEditor: React.FC<Props> = ({
     [ctas, database, defaultQueryLimit, dispatch, queryEditor],
   );
 
-  const formatCurrentQuery = useCallback(() => {
-    dispatch(formatQuery(queryEditor));
-  }, [dispatch, queryEditor]);
+  const formatCurrentQuery = useCallback(
+    (useShortcut?: boolean) => {
+      logAction(LOG_ACTIONS_SQLLAB_FORMAT_SQL, {
+        shortcut: Boolean(useShortcut),
+      });
+      dispatch(formatQuery(queryEditor));
+    },
+    [dispatch, queryEditor, logAction],
+  );
 
   const stopQuery = useCallback(() => {
     if (latestQuery && ['running', 'pending'].indexOf(latestQuery.state) >= 0) 
{
@@ -355,6 +373,7 @@ const SqlEditor: React.FC<Props> = ({
         descr: KEY_MAP[KeyboardShortcut.CtrlR],
         func: () => {
           if (queryEditor.sql.trim() !== '') {
+            logAction(LOG_ACTIONS_SQLLAB_RUN_QUERY, { shortcut: true });
             startQuery();
           }
         },
@@ -365,6 +384,7 @@ const SqlEditor: React.FC<Props> = ({
         descr: KEY_MAP[KeyboardShortcut.CtrlEnter],
         func: () => {
           if (queryEditor.sql.trim() !== '') {
+            logAction(LOG_ACTIONS_SQLLAB_RUN_QUERY, { shortcut: true });
             startQuery();
           }
         },
@@ -381,6 +401,7 @@ const SqlEditor: React.FC<Props> = ({
               descr: KEY_MAP[KeyboardShortcut.CtrlT],
             }),
         func: () => {
+          Logger.markTimeOrigin();
           dispatch(addNewQueryEditor());
         },
       },
@@ -395,14 +416,17 @@ const SqlEditor: React.FC<Props> = ({
               key: KeyboardShortcut.CtrlE,
               descr: KEY_MAP[KeyboardShortcut.CtrlE],
             }),
-        func: stopQuery,
+        func: () => {
+          logAction(LOG_ACTIONS_SQLLAB_STOP_QUERY, { shortcut: true });
+          stopQuery();
+        },
       },
       {
         name: 'formatQuery',
         key: KeyboardShortcut.CtrlShiftF,
         descr: KEY_MAP[KeyboardShortcut.CtrlShiftF],
         func: () => {
-          formatCurrentQuery();
+          formatCurrentQuery(true);
         },
       },
     ];
@@ -500,6 +524,13 @@ const SqlEditor: React.FC<Props> = ({
     !queryEditor.loaded;
 
   const loadQueryEditor = useEffectEvent(() => {
+    const duration = Logger.getTimestamp();
+    logAction(LOG_ACTIONS_SQLLAB_LOAD_TAB_STATE, {
+      duration,
+      queryEditorId: queryEditor.id,
+      inLocalStorage: Boolean(queryEditor.inLocalStorage),
+      hasLoaded: !shouldLoadQueryEditor,
+    });
     if (shouldLoadQueryEditor) {
       dispatch(switchQueryEditor(queryEditor, displayLimit));
     }
@@ -597,6 +628,7 @@ const SqlEditor: React.FC<Props> = ({
   });
 
   const getQueryCostEstimate = () => {
+    logAction(LOG_ACTIONS_SQLLAB_ESTIMATE_QUERY_COST, { shortcut: false });
     if (database) {
       dispatch(estimateQueryCost(queryEditor));
     }
@@ -650,7 +682,9 @@ const SqlEditor: React.FC<Props> = ({
             />
           </Menu.Item>
         )}
-        <Menu.Item onClick={formatCurrentQuery}>{t('Format SQL')}</Menu.Item>
+        <Menu.Item onClick={() => formatCurrentQuery()}>
+          {t('Format SQL')}
+        </Menu.Item>
         {!isEmpty(scheduledQueriesConf) && (
           <Menu.Item>
             <ScheduleQueryButton
@@ -688,6 +722,9 @@ const SqlEditor: React.FC<Props> = ({
         {allowCTAS && (
           <Menu.Item
             onClick={() => {
+              logAction(LOG_ACTIONS_SQLLAB_CREATE_TABLE_AS, {
+                shortcut: false,
+              });
               setShowCreateAsModal(true);
               setCreateAs(CtasEnum.Table);
             }}
@@ -699,6 +736,9 @@ const SqlEditor: React.FC<Props> = ({
         {allowCVAS && (
           <Menu.Item
             onClick={() => {
+              logAction(LOG_ACTIONS_SQLLAB_CREATE_VIEW_AS, {
+                shortcut: false,
+              });
               setShowCreateAsModal(true);
               setCreateAs(CtasEnum.View);
             }}
diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx 
b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
index 078276ad26..c9532fc2f2 100644
--- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
+++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
@@ -23,6 +23,7 @@ import { connect } from 'react-redux';
 import URI from 'urijs';
 import type { QueryEditor, SqlLabRootState } from 'src/SqlLab/types';
 import { FeatureFlag, styled, t, isFeatureEnabled } from '@superset-ui/core';
+import { Logger } from 'src/logger/LogUtils';
 import { Tooltip } from 'src/components/Tooltip';
 import { detectOS } from 'src/utils/common';
 import * as Actions from 'src/SqlLab/actions/sqlLab';
@@ -220,6 +221,7 @@ class TabbedSqlEditors extends 
React.PureComponent<TabbedSqlEditorsProps> {
       }
     }
     if (action === 'add') {
+      Logger.markTimeOrigin();
       this.newQueryEditor();
     }
   }
@@ -228,6 +230,14 @@ class TabbedSqlEditors extends 
React.PureComponent<TabbedSqlEditorsProps> {
     this.props.actions.removeQueryEditor(qe);
   }
 
+  onTabClicked = () => {
+    Logger.markTimeOrigin();
+    const noQueryEditors = this.props.queryEditors?.length === 0;
+    if (noQueryEditors) {
+      this.newQueryEditor();
+    }
+  };
+
   render() {
     const noQueryEditors = this.props.queryEditors?.length === 0;
     const editors = this.props.queryEditors?.map(qe => (
@@ -288,7 +298,7 @@ class TabbedSqlEditors extends 
React.PureComponent<TabbedSqlEditorsProps> {
         onChange={this.handleSelect}
         fullWidth={false}
         hideAdd={this.props.offline}
-        onTabClick={() => noQueryEditors && this.newQueryEditor()}
+        onTabClick={this.onTabClicked}
         onEdit={this.handleEdit}
         type={noQueryEditors ? 'card' : 'editable-card'}
         addIcon={
diff --git a/superset-frontend/src/logger/LogUtils.ts 
b/superset-frontend/src/logger/LogUtils.ts
index 2020cb67c0..913a3d5af7 100644
--- a/superset-frontend/src/logger/LogUtils.ts
+++ b/superset-frontend/src/logger/LogUtils.ts
@@ -70,6 +70,21 @@ export const LOG_ACTIONS_DRILL_BY_BREADCRUMB_CLICKED =
   'drill_by_breadcrumb_clicked';
 export const LOG_ACTIONS_SQLLAB_MONITOR_LOCAL_STORAGE_USAGE =
   'sqllab_monitor_local_storage_usage';
+export const LOG_ACTIONS_SQLLAB_CREATE_TABLE_AS = 'sqllab_create_table_as';
+export const LOG_ACTIONS_SQLLAB_CREATE_VIEW_AS = 'sqllab_create_view_as';
+export const LOG_ACTIONS_SQLLAB_RUN_QUERY = 'sqllab_run_query';
+export const LOG_ACTIONS_SQLLAB_STOP_QUERY = 'sqllab_stop_query';
+export const LOG_ACTIONS_SQLLAB_ESTIMATE_QUERY_COST =
+  'sqllab_estimate_query_cost';
+export const LOG_ACTIONS_SQLLAB_SAVE_QUERY = 'sqllab_save_query';
+export const LOG_ACTIONS_SQLLAB_SAVE_DATASET = 'sqllab_save_dataset';
+export const LOG_ACTIONS_SQLLAB_COPY_LINK = 'sqllab_copy_link';
+export const LOG_ACTIONS_SQLLAB_FORMAT_SQL = 'sqllab_format_sql';
+export const LOG_ACTIONS_SQLLAB_DOWNLOAD_CSV = 'sqllab_download_csv';
+export const LOG_ACTIONS_SQLLAB_COPY_RESULT_TO_CLIPBOARD =
+  'sqllab_copy_result_to_clipboard';
+export const LOG_ACTIONS_SQLLAB_CREATE_CHART = 'sqllab_create_chart';
+export const LOG_ACTIONS_SQLLAB_LOAD_TAB_STATE = 'sqllab_load_tab_state';
 
 // Log event types 
--------------------------------------------------------------
 export const LOG_EVENT_TYPE_TIMING = new Set([
@@ -77,6 +92,7 @@ export const LOG_EVENT_TYPE_TIMING = new Set([
   LOG_ACTIONS_RENDER_CHART,
   LOG_ACTIONS_HIDE_BROWSER_TAB,
   LOG_ACTIONS_SQLLAB_FETCH_FAILED_QUERY,
+  LOG_ACTIONS_SQLLAB_LOAD_TAB_STATE,
 ]);
 export const LOG_EVENT_TYPE_USER = new Set([
   LOG_ACTIONS_MOUNT_DASHBOARD,
diff --git a/superset-frontend/src/logger/useLogAction.test.ts 
b/superset-frontend/src/logger/useLogAction.test.ts
new file mode 100644
index 0000000000..bf314ff0ee
--- /dev/null
+++ b/superset-frontend/src/logger/useLogAction.test.ts
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import configureStore from 'redux-mock-store';
+import thunk from 'redux-thunk';
+import { renderHook } from '@testing-library/react-hooks';
+import { createWrapper } from 'spec/helpers/testing-library';
+import useLogAction from './useLogAction';
+import { LOG_ACTIONS_SQLLAB_COPY_LINK } from './LogUtils';
+import { LOG_EVENT } from './actions';
+
+const middlewares = [thunk];
+const mockStore = configureStore(middlewares);
+
+test('dispatches logEvent action with static EventData', () => {
+  const staticEventData = { staticEventKey: 'value1' };
+  const store = mockStore();
+  const { result } = renderHook(() => useLogAction(staticEventData), {
+    wrapper: createWrapper({
+      useRedux: true,
+      store,
+    }),
+  });
+  result.current(LOG_ACTIONS_SQLLAB_COPY_LINK, { count: 1 });
+  store.getActions();
+  expect(store.getActions()).toEqual([
+    {
+      type: LOG_EVENT,
+      payload: {
+        eventName: LOG_ACTIONS_SQLLAB_COPY_LINK,
+        eventData: {
+          payload: {
+            ...staticEventData,
+            count: 1,
+          },
+        },
+      },
+    },
+  ]);
+});
diff --git a/superset-frontend/src/logger/useLogAction.ts 
b/superset-frontend/src/logger/useLogAction.ts
new file mode 100644
index 0000000000..3f8cdcc50f
--- /dev/null
+++ b/superset-frontend/src/logger/useLogAction.ts
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { useCallback } from 'react';
+import { useDispatch } from 'react-redux';
+import { logEvent } from 'src/logger/actions';
+
+export default function useLogAction(staticEventData: Record<string, any>) {
+  const dispatch = useDispatch();
+  const logAction = useCallback<typeof logEvent>(
+    (type, payload) =>
+      dispatch(
+        logEvent(type, {
+          payload: {
+            ...staticEventData,
+            ...payload,
+          },
+        }),
+      ),
+    [staticEventData, dispatch],
+  );
+
+  return logAction;
+}

Reply via email to