From b7be2e3b6e5382c2889fcadf05f0e3dfeb6a2b8b Mon Sep 17 00:00:00 2001 From: Vemparala Surya Vamsi <121419957+vsvamsi1@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:17:19 +0530 Subject: [PATCH] chore: Initiate execution of google.api script at editor level (#30837) ## Description Earlier we were executing the google.api script quiet early during page load for every route. We have now initiated as lazily as possible at the datasource editor component level. #### PR fixes following issue(s) Fixes #30656 #### Type of change - Chore (housekeeping or task changes that don't impact user perception) #### How Has This Been Tested? - [x] Manual - [ ] JUnit - [ ] Jest - [x] 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/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#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 ## Summary by CodeRabbit - **New Features** - Introduced dynamic loading of the Google API script to enhance application configuration flexibility. - **Refactor** - Removed static Google APIs JavaScript library loading from `index.html`. - Enhanced `DatasourcesSagas` with new Google API execution logic. --- app/client/public/index.html | 30 +-------------------- app/client/src/sagas/DatasourcesSagas.ts | 2 ++ app/client/src/sagas/loadGoogleApi.ts | 33 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 app/client/src/sagas/loadGoogleApi.ts diff --git a/app/client/public/index.html b/app/client/public/index.html index f20d72008a..df4b23c626 100755 --- a/app/client/public/index.html +++ b/app/client/public/index.html @@ -98,35 +98,7 @@ head && head.appendChild(script); } - // This function is triggered on load of google apis javascript library - // Even though the script is loaded asynchronously, in case of firefox run on windows - // The gapi script is getting loaded even before the last script of index.html - // Hence defining this function before loading gapi - // For more info: https://github.com/appsmithorg/appsmith/issues/21033 - const gapiLoaded = () => { - window.googleAPIsLoaded = true; - }; - const onError = () => { - window.googleAPIsLoaded = false; - }; - - if (!AIRGAPPED) { - // Adding this Library to access google file picker API in case of limiting google sheet access - const script2 = document.createElement("script"); - script2.crossOrigin = "anonymous"; - script2.async = true; - script2.defer = true; - script2.src = "https://apis.google.com/js/api.js"; - script2.id = "googleapis"; - script2.onload = () => { - gapiLoaded(); - }; - script2.onerror = () => { - onError(); - }; - const headElement = document.getElementsByTagName("head")[0]; - headElement && headElement.appendChild(script2); - } + diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index dffc23a485..43c9323495 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -174,6 +174,7 @@ import { getIsEditorPaneSegmentsEnabled } from "@appsmith/selectors/featureFlags import { identifyEntityFromPath } from "../navigation/FocusEntity"; import { MAX_DATASOURCE_SUGGESTIONS } from "constants/DatasourceEditorConstants"; import { getFromServerWhenNoPrefetchedResult } from "./helper"; +import { executeGoogleApi } from "./loadGoogleApi"; function* fetchDatasourcesSaga( action: ReduxAction< @@ -2029,6 +2030,7 @@ function* loadFilePickerSaga() { // This adds overlay on document body // This is done for google sheets file picker, as file picker needs to be shown on blank page // when overlay needs to be shown, we get showPicker search param in redirect url + yield executeGoogleApi(); const appsmithToken = localStorage.getItem(APPSMITH_TOKEN_STORAGE_KEY); const search = new URLSearchParams(window.location.search); const isShowFilePicker = search.get(SHOW_FILE_PICKER_KEY); diff --git a/app/client/src/sagas/loadGoogleApi.ts b/app/client/src/sagas/loadGoogleApi.ts new file mode 100644 index 0000000000..969ef4e134 --- /dev/null +++ b/app/client/src/sagas/loadGoogleApi.ts @@ -0,0 +1,33 @@ +import { isAirgapped } from "@appsmith/utils/airgapHelpers"; + +async function loadScript(src: string) { + return new Promise(function (resolve, reject) { + const s = document.createElement("script"); + s.src = src; + s.onload = resolve; + s.onerror = reject; + s.crossOrigin = "anonymous"; + s.id = "googleapis"; + const headElement = document.getElementsByTagName("head")[0]; + headElement && headElement.appendChild(s); + }); +} + +export const executeGoogleApi = async () => { + const airGapped = isAirgapped(); + // if the googleAPIsLoaded is already loaded, do not load it again. + if (airGapped || (window as any).googleAPIsLoaded) { + return; + } + const gapiLoaded = () => { + (window as any).googleAPIsLoaded = true; + }; + const onError = () => { + (window as any).googleAPIsLoaded = false; + }; + + await loadScript("https://apis.google.com/js/api.js").then( + gapiLoaded, + onError, + ); +};