chore: analytic events added for gsheet (#23171)
## Description This PR adds: - Analytics events for google sheet datasource. #### PR fixes following issue(s) Fixes #22805 > if no issue exists, please create an issue and ask the maintainers about this first > > #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change - Chore (housekeeping or task changes that don't impact user perception) > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: “sneha122” <“sneha@appsmith.com”>
This commit is contained in:
parent
8ee9da291c
commit
885de0466b
|
|
@ -366,6 +366,7 @@ export const GSHEET_AUTHORIZATION_ERROR =
|
|||
"Authorisation failed, to continue using this data source authorize now.";
|
||||
export const GSHEET_FILES_NOT_SELECTED =
|
||||
"Datasource does not have access to any files, please authorize google sheets to use this data source";
|
||||
export const FILES_NOT_SELECTED_EVENT = () => "Files not selected";
|
||||
|
||||
export const LOCAL_STORAGE_QUOTA_EXCEEDED_MESSAGE = () =>
|
||||
"Error saving a key in localStorage. You have exceeded the allowed storage size limit";
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {
|
|||
getDatasourceFormButtonConfig,
|
||||
getPlugin,
|
||||
getPluginDocumentationLinks,
|
||||
getDatasourceScopeValue,
|
||||
} from "selectors/entitiesSelector";
|
||||
import type { ActionDataState } from "reducers/entityReducers/actionsReducer";
|
||||
import type { JSONtoFormProps } from "../DataSourceEditor/JSONtoForm";
|
||||
|
|
@ -97,6 +98,7 @@ interface StateProps extends JSONtoFormProps {
|
|||
gsheetToken?: string;
|
||||
gsheetProjectID?: string;
|
||||
documentationLink: string | undefined;
|
||||
scopeValue?: string;
|
||||
}
|
||||
interface DatasourceFormFunctions {
|
||||
discardTempDatasource: () => void;
|
||||
|
|
@ -286,6 +288,7 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
|||
pageId,
|
||||
plugin,
|
||||
pluginPackageName,
|
||||
scopeValue,
|
||||
} = this.props;
|
||||
const params: string = location.search;
|
||||
const viewMode =
|
||||
|
|
@ -426,17 +429,15 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
|||
}
|
||||
showDatasourceSavedText={!isGoogleSheetPlugin}
|
||||
/>
|
||||
<div style={{ marginTop: "30px" }}>
|
||||
{!_.isNil(formConfig) &&
|
||||
!_.isNil(datasource) &&
|
||||
!hideDatasourceSection ? (
|
||||
<DatasourceInformation
|
||||
config={formConfig[0]}
|
||||
datasource={datasource}
|
||||
viewMode={!!viewMode}
|
||||
/>
|
||||
) : undefined}
|
||||
</div>
|
||||
{!_.isNil(formConfig) &&
|
||||
!_.isNil(datasource) &&
|
||||
!hideDatasourceSection ? (
|
||||
<DatasourceInformation
|
||||
config={formConfig[0]}
|
||||
datasource={datasource}
|
||||
viewMode={!!viewMode}
|
||||
/>
|
||||
) : undefined}
|
||||
</ViewModeWrapper>
|
||||
)}
|
||||
{/* Render datasource form call-to-actions */}
|
||||
|
|
@ -449,6 +450,7 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
|
|||
getSanitizedFormData={_.memoize(this.getSanitizedData)}
|
||||
isInvalid={this.validate()}
|
||||
pageId={pageId}
|
||||
scopeValue={scopeValue}
|
||||
shouldDisplayAuthMessage={!isGoogleSheetPlugin}
|
||||
shouldRender={!viewMode}
|
||||
triggerSave={this.props.isDatasourceBeingSavedFromPopup}
|
||||
|
|
@ -496,6 +498,13 @@ const mapStateToProps = (state: AppState, props: any) => {
|
|||
|
||||
merge(initialValues, datasource);
|
||||
|
||||
// get scopeValue to be shown in analytical events
|
||||
const scopeValue = getDatasourceScopeValue(
|
||||
state,
|
||||
datasourceId,
|
||||
DATASOURCE_SAAS_FORM,
|
||||
);
|
||||
|
||||
const datasourceButtonConfiguration = getDatasourceFormButtonConfig(
|
||||
state,
|
||||
formData?.pluginId,
|
||||
|
|
@ -551,6 +560,7 @@ const mapStateToProps = (state: AppState, props: any) => {
|
|||
canCreateDatasourceActions,
|
||||
gsheetToken,
|
||||
gsheetProjectID,
|
||||
scopeValue,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -335,20 +335,21 @@ function ReconnectDatasourceModal() {
|
|||
const status = queryParams.get("response_status");
|
||||
const display_message = queryParams.get("display_message");
|
||||
const variant = Variant.danger;
|
||||
|
||||
const oauthReason = status;
|
||||
const isReconnectDS = true;
|
||||
AnalyticsUtil.logEvent("DATASOURCE_AUTHORIZE_RESULT", {
|
||||
dsName,
|
||||
oauthReason,
|
||||
orgId,
|
||||
pluginName,
|
||||
isReconnectDS,
|
||||
});
|
||||
if (status !== AuthorizationStatus.SUCCESS) {
|
||||
const message =
|
||||
status === AuthorizationStatus.APPSMITH_ERROR
|
||||
? OAUTH_AUTHORIZATION_APPSMITH_ERROR
|
||||
: OAUTH_AUTHORIZATION_FAILED;
|
||||
Toaster.show({ text: display_message || message, variant });
|
||||
const oAuthStatus = status;
|
||||
AnalyticsUtil.logEvent("UPDATE_DATASOURCE", {
|
||||
dsName,
|
||||
oAuthStatus,
|
||||
orgId,
|
||||
pluginName,
|
||||
});
|
||||
} else if (queryDatasourceId) {
|
||||
dispatch(loadFilePickerAction());
|
||||
dispatch(getOAuthAccessToken(queryDatasourceId));
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ interface Props {
|
|||
triggerSave?: boolean;
|
||||
isFormDirty?: boolean;
|
||||
datasourceDeleteTrigger: () => void;
|
||||
scopeValue?: string;
|
||||
}
|
||||
|
||||
export type DatasourceFormButtonTypes = Record<string, string[]>;
|
||||
|
|
@ -121,6 +122,7 @@ function DatasourceAuth({
|
|||
shouldDisplayAuthMessage = true,
|
||||
triggerSave,
|
||||
isFormDirty,
|
||||
scopeValue,
|
||||
}: Props) {
|
||||
const authType =
|
||||
formData && "authType" in formData
|
||||
|
|
@ -181,20 +183,19 @@ function DatasourceAuth({
|
|||
if (status && shouldNotify) {
|
||||
const display_message = search.get("display_message");
|
||||
const variant = Variant.danger;
|
||||
|
||||
const oauthReason = status;
|
||||
AnalyticsUtil.logEvent("DATASOURCE_AUTHORIZE_RESULT", {
|
||||
dsName,
|
||||
oauthReason,
|
||||
orgId,
|
||||
pluginName,
|
||||
});
|
||||
if (status !== AuthorizationStatus.SUCCESS) {
|
||||
const message =
|
||||
status === AuthorizationStatus.APPSMITH_ERROR
|
||||
? OAUTH_AUTHORIZATION_APPSMITH_ERROR
|
||||
: OAUTH_AUTHORIZATION_FAILED;
|
||||
Toaster.show({ text: display_message || message, variant });
|
||||
const oAuthStatus = status;
|
||||
AnalyticsUtil.logEvent("UPDATE_DATASOURCE", {
|
||||
dsName,
|
||||
oAuthStatus,
|
||||
orgId,
|
||||
pluginName,
|
||||
});
|
||||
} else {
|
||||
dispatch(getOAuthAccessToken(datasourceId));
|
||||
}
|
||||
|
|
@ -295,6 +296,12 @@ function DatasourceAuth({
|
|||
),
|
||||
);
|
||||
}
|
||||
AnalyticsUtil.logEvent("DATASOURCE_AUTHORIZE_CLICK", {
|
||||
dsName,
|
||||
orgId,
|
||||
pluginName,
|
||||
scopeValue,
|
||||
});
|
||||
};
|
||||
|
||||
const createMode = datasourceId === TEMP_DATASOURCE_ID;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import {
|
|||
getDatasourceActionRouteInfo,
|
||||
getPlugin,
|
||||
getEditorConfig,
|
||||
getPluginNameFromId,
|
||||
} from "selectors/entitiesSelector";
|
||||
import type {
|
||||
UpdateDatasourceSuccessAction,
|
||||
|
|
@ -88,6 +89,7 @@ import {
|
|||
DATASOURCE_DELETE,
|
||||
DATASOURCE_UPDATE,
|
||||
DATASOURCE_VALID,
|
||||
FILES_NOT_SELECTED_EVENT,
|
||||
GSHEET_AUTHORISED_FILE_IDS_KEY,
|
||||
OAUTH_APPSMITH_TOKEN_NOT_FOUND,
|
||||
OAUTH_AUTHORIZATION_APPSMITH_ERROR,
|
||||
|
|
@ -1232,6 +1234,23 @@ function* filePickerActionCallbackSaga(
|
|||
// Once files are selected in case of import, set this flag
|
||||
set(datasource, "isConfigured", true);
|
||||
|
||||
// event in case files are not selected
|
||||
if (action === FilePickerActionStatus.CANCEL) {
|
||||
const oauthReason = createMessage(FILES_NOT_SELECTED_EVENT);
|
||||
const dsName = datasource?.name;
|
||||
const orgId = datasource?.workspaceId;
|
||||
const pluginName: string = yield select(
|
||||
getPluginNameFromId,
|
||||
datasource?.pluginId,
|
||||
);
|
||||
AnalyticsUtil.logEvent("DATASOURCE_AUTHORIZE_RESULT", {
|
||||
dsName,
|
||||
oauthReason,
|
||||
orgId,
|
||||
pluginName,
|
||||
});
|
||||
}
|
||||
|
||||
// Once users selects/cancels the file selection,
|
||||
// Sending sheet ids selected as part of datasource
|
||||
// config properties in order to save it in database
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import { InstallState } from "reducers/uiReducers/libraryReducer";
|
|||
import recommendedLibraries from "pages/Editor/Explorer/Libraries/recommendedLibraries";
|
||||
import type { TJSLibrary } from "workers/common/JSLibrary";
|
||||
import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import { getFormValues } from "redux-form";
|
||||
|
||||
export const getEntities = (state: AppState): AppState["entities"] =>
|
||||
state.entities;
|
||||
|
|
@ -1037,3 +1038,28 @@ export const getAllDatasourceTableKeys = createSelector(
|
|||
return tables;
|
||||
},
|
||||
);
|
||||
|
||||
export const getDatasourceScopeValue = (
|
||||
state: AppState,
|
||||
datasourceId: string,
|
||||
formName: string,
|
||||
) => {
|
||||
const formData = getFormValues(formName)(state) as Datasource;
|
||||
const { plugins } = state.entities;
|
||||
const { formConfigs } = plugins;
|
||||
const datasource = getDatasource(state, datasourceId);
|
||||
const pluginId = get(datasource, "pluginId", "");
|
||||
const formConfig = formConfigs[pluginId];
|
||||
if (!formConfig || (!!formConfig && formConfig.length === 0)) {
|
||||
return null;
|
||||
}
|
||||
const configProperty = "datasourceConfiguration.authentication.scopeString";
|
||||
const scopeValue = get(formData, configProperty);
|
||||
const options = formConfig[0]?.children?.find(
|
||||
(child: any) => child?.configProperty === configProperty,
|
||||
)?.options;
|
||||
const label = options?.find(
|
||||
(option: any) => option.value === scopeValue,
|
||||
)?.label;
|
||||
return label;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ export type EventName =
|
|||
| "CONVERSION_FAILURE"
|
||||
| "CONVERT_AUTO_TO_FIXED"
|
||||
| "CONVERT_FIXED_TO_AUTO"
|
||||
| "DATASOURCE_AUTHORIZE_CLICK"
|
||||
| "DATASOURCE_AUTHORIZE_RESULT"
|
||||
| AI_EVENTS;
|
||||
|
||||
export type AI_EVENTS =
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user