From 662df2d36d1d590d504d55f20c895a1a882cdf7f Mon Sep 17 00:00:00 2001 From: Abhijeet <41686026+abhvsn@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:19:22 +0530 Subject: [PATCH 01/11] chore: Supress the failure in case DB url is not found in CI (#36796) https://theappsmith.slack.com/archives/C0134BAVDB4/p1728541176951609 (cherry picked from commit b16aaafa515bcdf371262dcbca149f83e4fc1d64) --- .github/workflows/ci-test-custom-script.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci-test-custom-script.yml b/.github/workflows/ci-test-custom-script.yml index 2062ecb29ce9..575110b1b825 100644 --- a/.github/workflows/ci-test-custom-script.yml +++ b/.github/workflows/ci-test-custom-script.yml @@ -204,7 +204,6 @@ jobs: db_url=$(grep -oP 'APPSMITH_DB_URL=\K[^ ]+' cicontainerlocal/stacks/configuration/docker.env || echo "") if [[ -z "$db_url" ]]; then echo "::error::APPSMITH_DB_URL not found in the environment file" - exit 1 fi if [[ $db_url == "postgresql"* ]]; then echo "Database type: Postgres. Ensure PostgreSQL-specific configurations are in place." From b086761e8b64fcc21242d71726f7dabdbb224902 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Mon, 14 Oct 2024 17:11:01 +0530 Subject: [PATCH 02/11] chore: Use Lettuce client to run clear keys across Redis nodes (#36862) --- .../Migration063CacheBustSpringBoot3_3.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration063CacheBustSpringBoot3_3.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration063CacheBustSpringBoot3_3.java index 7ca5077babad..217feb8abd15 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration063CacheBustSpringBoot3_3.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/db/ce/Migration063CacheBustSpringBoot3_3.java @@ -5,7 +5,12 @@ import io.mongock.api.annotations.RollbackExecution; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.data.redis.core.ReactiveRedisOperations; +import org.springframework.data.redis.core.ScanOptions; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.nio.ByteBuffer; @Slf4j @ChangeUnit(order = "063", id = "reset_session_oauth2_spring_3_3") @@ -16,12 +21,25 @@ public void rollbackExecution() {} @Execution public void execute( - @Qualifier("reactiveRedisTemplate") final ReactiveRedisTemplate reactiveRedisTemplate) { - reactiveRedisTemplate - .getConnectionFactory() - .getReactiveConnection() - .serverCommands() - .flushDb() - .block(); + @Qualifier("reactiveRedisOperations") ReactiveRedisOperations reactiveRedisOperations) { + scanForKeysAcrossCluster(reactiveRedisOperations, "*").block(); + } + + private Mono scanForKeysAcrossCluster( + ReactiveRedisOperations reactiveRedisOperations, String pattern) { + return reactiveRedisOperations + .execute(connection -> { + Flux scanFlux = connection + .keyCommands() + .scan(ScanOptions.scanOptions() + .match(pattern) + .count(1000) + .build()); + return scanFlux.flatMap(scannedKey -> { + return connection.keyCommands().del(scannedKey); + }) + .then(); + }) + .then(); } } From 455abf81652a8664e37369631f2cb94da34a0054 Mon Sep 17 00:00:00 2001 From: Shrikant Sharat Kandula Date: Tue, 26 Nov 2024 12:22:43 +0530 Subject: [PATCH 03/11] fix: Signup from OAuth not being detected correctly (#37697) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue where the detection for signup when using OAuth was not being handled correctly. [Slack conversation](https://theappsmith.slack.com/archives/C02K2MZERSL/p1732600773587469?thread_ts=1732554015.110689&cid=C02K2MZERSL). ## Automation /test sanity ### :mag: Cypress test results > [!WARNING] > Workflow run: > Commit: d53fcdf0451a5911471b05678e03831a0d9a632a > Cypress dashboard. > Tags: @tag.Sanity > Spec: > It seems like **no tests ran** πŸ˜”. We are not able to recognize it, please check workflow here. >
Tue, 26 Nov 2024 06:16:02 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **New Features** - Improved handling of user authentication success, enhancing the flow for email verification and OAuth2 authentication. - **Refactor** - Simplified the logic for determining user sign-up or login status. - Streamlined the method for handling OAuth2 redirects, improving clarity and maintainability. --- .../ce/AuthenticationSuccessHandlerCE.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java index 40e9e0ea9bbc..1b4054ddb248 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/authentication/handlers/ce/AuthenticationSuccessHandlerCE.java @@ -252,8 +252,7 @@ public Mono onAuthenticationSuccess( // creation) or if this was a login (existing user). What we do here to identify this, is an approximation. // If and when we find a better way to do identify this, let's please move away from this approximation. // If the user object was created within the last 5 seconds, we treat it as a new user. - final boolean oauthIsFromSignup = - user.getCreatedAt().isAfter(Instant.now().minusSeconds(5)); + isFromSignup = user.getCreatedAt().isAfter(Instant.now().minusSeconds(5)); // Check the existing login source with the authentication source and then update the login source, // if they are not the same. @@ -270,19 +269,20 @@ public Mono onAuthenticationSuccess( .subscribeOn(Schedulers.boundedElastic()) .subscribe(); } - if (oauthIsFromSignup) { + if (isFromSignup) { + final boolean isFromSignupFinal = isFromSignup; redirectionMono = workspaceServiceHelper .isCreateWorkspaceAllowed(TRUE) .flatMap(isCreateWorkspaceAllowed -> { if (isCreateWorkspaceAllowed.equals(Boolean.TRUE)) { return createDefaultApplication(defaultWorkspaceId, authentication) .flatMap(application -> handleOAuth2Redirect( - webFilterExchange, application, oauthIsFromSignup)); + webFilterExchange, application, isFromSignupFinal)); } - return handleOAuth2Redirect(webFilterExchange, null, oauthIsFromSignup); + return handleOAuth2Redirect(webFilterExchange, null, isFromSignupFinal); }); } else { - redirectionMono = handleOAuth2Redirect(webFilterExchange, null, oauthIsFromSignup); + redirectionMono = handleOAuth2Redirect(webFilterExchange, null, isFromSignup); } } else { // form type signup/login handler @@ -290,6 +290,7 @@ public Mono onAuthenticationSuccess( webFilterExchange, defaultWorkspaceId, authentication, isFromSignup, createDefaultApplication); } + final boolean isFromSignupFinal = isFromSignup; Mono finalRedirectionMono = redirectionMono; return sessionUserService .getCurrentUser() @@ -307,7 +308,7 @@ public Mono onAuthenticationSuccess( modeOfLogin = ((OAuth2AuthenticationToken) authentication).getAuthorizedClientRegistrationId(); } - if (isFromSignup) { + if (isFromSignupFinal) { final String inviteToken = currentUser.getInviteToken(); final boolean isFromInvite = inviteToken != null; From 9a285aa9989600cc5db91bde4ca11e7ab04c5213 Mon Sep 17 00:00:00 2001 From: Abhijeet <41686026+abhvsn@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:15:24 +0530 Subject: [PATCH 04/11] fix: Super user cache eviction when user is added via env variable (#37785) (cherry picked from commit 4727b4da995e14cd7ff4e1616b15a47b545f5ac1) --- .../appsmith/server/migrations/DatabaseChangelog2.java | 5 ++--- .../server/migrations/MigrationHelperMethods.java | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java index 24acdcdda67a..ba30d97b5614 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog2.java @@ -28,7 +28,6 @@ import com.appsmith.server.helpers.TextUtils; import com.appsmith.server.migrations.solutions.UpdateSuperUserMigrationHelper; import com.appsmith.server.repositories.CacheableRepositoryHelper; -import com.appsmith.server.repositories.PermissionGroupRepository; import com.appsmith.server.solutions.PolicySolution; import com.github.cloudyrock.mongock.ChangeLog; import com.github.cloudyrock.mongock.ChangeSet; @@ -451,7 +450,7 @@ public static void doAddPermissionGroupIndex(MongoTemplate mongoTemplate) { @ChangeSet(order = "10000", id = "update-super-users", author = "", runAlways = true) public void updateSuperUsers( MongoTemplate mongoTemplate, - PermissionGroupRepository permissionGroupRepository, + CacheableRepositoryHelper cacheableRepositoryHelper, PolicySolution policySolution, PolicyGenerator policyGenerator) { // Read the admin emails from the environment and update the super users accordingly @@ -497,7 +496,7 @@ public void updateSuperUsers( Set oldSuperUsers = instanceAdminPG.getAssignedToUserIds(); Set updatedUserIds = findSymmetricDiff(oldSuperUsers, userIds); - evictPermissionCacheForUsers(updatedUserIds, mongoTemplate, permissionGroupRepository); + evictPermissionCacheForUsers(updatedUserIds, mongoTemplate, cacheableRepositoryHelper); Update update = new Update().set(PermissionGroup.Fields.assignedToUserIds, userIds); mongoTemplate.updateFirst(permissionGroupQuery, update, PermissionGroup.class); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java index 51abd5c67ce1..277a3ac5768e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/MigrationHelperMethods.java @@ -21,7 +21,7 @@ import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.CollectionUtils; -import com.appsmith.server.repositories.PermissionGroupRepository; +import com.appsmith.server.repositories.CacheableRepositoryHelper; import com.fasterxml.jackson.databind.ObjectMapper; import net.minidev.json.JSONObject; import org.apache.commons.lang.StringUtils; @@ -211,7 +211,7 @@ public static void migrateGoogleSheetsActionsToUqi(ApplicationJson applicationJs } public static void evictPermissionCacheForUsers( - Set userIds, MongoTemplate mongoTemplate, PermissionGroupRepository permissionGroupRepository) { + Set userIds, MongoTemplate mongoTemplate, CacheableRepositoryHelper cacheableRepositoryHelper) { if (userIds == null || userIds.isEmpty()) { // Nothing to do here. @@ -223,8 +223,8 @@ public static void evictPermissionCacheForUsers( User user = mongoTemplate.findOne(query, User.class); if (user != null) { // blocking call for cache eviction to ensure its subscribed immediately before proceeding further. - permissionGroupRepository - .evictAllPermissionGroupCachesForUser(user.getEmail(), user.getTenantId()) + cacheableRepositoryHelper + .evictPermissionGroupsUser(user.getEmail(), user.getTenantId()) .block(); } }); From 4df3d451828887d5138a5a29915454b3364b0e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Csneha122=E2=80=9D?= <β€œsneha@appsmith.com”> Date: Thu, 28 Nov 2024 14:11:09 +0530 Subject: [PATCH 05/11] chore: Google sheet shared drive support added behind a flag (#37776) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR hides shared drive support for Google Sheets Integration behind a feature flag as we need to do thorough testing for it. The feature flag implementation done in this PR involves passing feature flags from server to google sheets plugin module. This temporary feature flagging solution tech debt can be removed once the testing is done and once we would release this feature to all. **Why feature flags are only available at server module?** Because they have a dependency on UserIdentifierService, SessionUserService, TenantService etc which exists at server module. Supporting feature flags out of the box at plugin module level would require significant efforts to migrate these dependencies. Fixes #37714 _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ /ok-to-test tags="@tag.Authentication, @tag.Datasource" > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 47f08f9903e78e050f18ad304dd736acb61b8b28 > Cypress dashboard. > Tags: `@tag.Authentication, @tag.Datasource` > Spec: >
Thu, 28 Nov 2024 07:38:58 UTC Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No - **New Features** - Introduced support for Google Sheets shared drive through feature flags. - Added new methods to handle feature flags in plugin execution and triggering processes. - Enhanced action execution and triggering logic to utilize feature flags for dynamic behavior. - **Bug Fixes** - Improved error handling for plugin execution processes. - **Tests** - Integrated `FeatureFlagService` into the testing framework for enhanced test coverage. - Expanded test scenarios to include various response types and error conditions. --------- Co-authored-by: β€œsneha122” <β€œsneha@appsmith.com”> --- .../external/enums/FeatureFlagEnum.java | 1 + .../external/plugins/PluginExecutor.java | 44 +++++++++++++++++++ .../com/external/config/ExecutionMethod.java | 9 +++- .../com/external/config/FileListMethod.java | 19 +++++--- .../com/external/config/TriggerMethod.java | 13 +++++- .../external/plugins/GoogleSheetsPlugin.java | 33 +++++++++++--- .../PluginTriggerSolutionCEImpl.java | 15 +++++-- .../solutions/PluginTriggerSolutionImpl.java | 12 ++++- .../ActionExecutionSolutionImpl.java | 7 ++- .../DatasourceTriggerSolutionImpl.java | 7 ++- .../ce/ActionExecutionSolutionCEImpl.java | 18 ++++++-- .../ce/DatasourceTriggerSolutionCEImpl.java | 14 +++++- .../ce/ActionExecutionSolutionCEImplTest.java | 7 ++- .../ce/ActionExecutionSolutionCETest.java | 16 ++++++- 14 files changed, 185 insertions(+), 30 deletions(-) diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java index e3e96745784a..9849422cd531 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java @@ -14,6 +14,7 @@ public enum FeatureFlagEnum { APP_NAVIGATION_LOGO_UPLOAD, release_embed_hide_share_settings_enabled, rollout_datasource_test_rate_limit_enabled, + release_google_sheets_shared_drive_support_enabled, // Deprecated CE flags over here release_git_autocommit_feature_enabled, diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java index d912594f4a5a..a95a7c2988ac 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java @@ -247,6 +247,50 @@ default Mono executeParameterizedWithMetrics( .tap(Micrometer.observation(observationRegistry)); } + // TODO: Following methods of executeParameterizedWithFlags, executeParameterizedWithMetricsAndFlags, + // triggerWithFlags are + // added + // to support feature flags in the plugin modules. Current implementation of featureFlagService is only available in + // server module + // and not available in any of the plugin modules due to dependencies on SessionUserService, TenantService etc. + // Hence, these methods are added to support feature flags in the plugin modules. + // Ideal solution would be to move featureFlagService and its dependencies to the shared interface module + // But this is a bigger change and will be done in future. Current change of passing flags was done to resolve + // release blocker + // https://github.com/appsmithorg/appsmith/issues/37714 + // Once thorogh testing of shared drive support is done, we can remove this tech debt of passing feature flags like + // this. + default Mono executeParameterizedWithFlags( + C connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + Map featureFlagMap) { + return this.executeParameterized(connection, executeActionDTO, datasourceConfiguration, actionConfiguration); + } + + default Mono executeParameterizedWithMetricsAndFlags( + C connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + ObservationRegistry observationRegistry, + Map featureFlagMap) { + return this.executeParameterizedWithFlags( + connection, executeActionDTO, datasourceConfiguration, actionConfiguration, featureFlagMap) + .tag("plugin", this.getClass().getName()) + .name(ACTION_EXECUTION_PLUGIN_EXECUTION) + .tap(Micrometer.observation(observationRegistry)); + } + + default Mono triggerWithFlags( + C connection, + DatasourceConfiguration datasourceConfiguration, + TriggerRequestDTO request, + Map featureFlagMap) { + return this.trigger(connection, datasourceConfiguration, request); + } + /** * This function is responsible for preparing the action and datasource configurations to be ready for execution. * diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java index ae6bef0a7c94..552f61f9323d 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java @@ -77,7 +77,9 @@ default Mono executePrerequisites(MethodConfig methodConfig, OAuth2 oaut return Mono.just(true); } - WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig); + default WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig) { + return null; + } default JsonNode transformExecutionResponse( JsonNode response, MethodConfig methodConfig, Set userAuthorizedSheetIds) { @@ -102,4 +104,9 @@ default Map getDataTypeConversionMap() { conversionMap.put(DataType.FLOAT, DataType.DOUBLE); return conversionMap; } + + default WebClient.RequestHeadersSpec getExecutionClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return getExecutionClient(webClient, methodConfig); + } } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java index 2d6b3aea8e17..4e092ee38022 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java @@ -1,5 +1,6 @@ package com.external.config; +import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; import com.external.constants.ErrorMessages; import com.external.enums.GoogleSheetMethodEnum; @@ -24,8 +25,9 @@ * API reference: https://developers.google.com/sheets/api/guides/migration#list_spreadsheets_for_the_authenticated_user */ public class FileListMethod implements ExecutionMethod, TriggerMethod { - ObjectMapper objectMapper; + private final String SHARED_DRIVE_PARAMS = + "&includeItemsFromAllDrives=true&supportsAllDrives=true&corpora=allDrives"; public FileListMethod(ObjectMapper objectMapper) { this.objectMapper = objectMapper; @@ -37,10 +39,16 @@ public boolean validateExecutionMethodRequest(MethodConfig methodConfig) { } @Override - public WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig) { + public WebClient.RequestHeadersSpec getExecutionClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Boolean isSharedDriveSupportEnabled = featureFlagMap.getOrDefault( + FeatureFlagEnum.release_google_sheets_shared_drive_support_enabled.name(), Boolean.FALSE); UriComponentsBuilder uriBuilder = getBaseUriBuilder( this.BASE_DRIVE_API_URL, - "?includeItemsFromAllDrives=true&supportsAllDrives=true&orderBy=name&q=mimeType%3D'application%2Fvnd.google-apps.spreadsheet'%20and%20trashed%3Dfalse", + "?orderBy=name&q=mimeType%3D'application%2Fvnd.google-apps.spreadsheet'%20and%20trashed%3Dfalse" + + (isSharedDriveSupportEnabled.equals(Boolean.TRUE) ? SHARED_DRIVE_PARAMS : ""), true); return webClient @@ -74,8 +82,9 @@ public boolean validateTriggerMethodRequest(MethodConfig methodConfig) { } @Override - public WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig) { - return this.getExecutionClient(webClient, methodConfig); + public WebClient.RequestHeadersSpec getTriggerClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return this.getExecutionClientWithFlags(webClient, methodConfig, featureFlagMap); } @Override diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java index 3528aea5db6b..0a385e64e770 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.springframework.web.reactive.function.client.WebClient; +import java.util.Map; import java.util.Set; /** @@ -21,7 +22,17 @@ public interface TriggerMethod { /** * Returns with the specification required to hit that particular trigger request */ - WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig); + default WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig) { + return null; + } + + /** + * Returns with the specification required to hit that particular trigger request + */ + default WebClient.RequestHeadersSpec getTriggerClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return getTriggerClient(webClient, methodConfig); + } /** * Transforms the response from the end point into an Appsmith friendly structure diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java index f336d54b8fc2..f006c050dd36 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java @@ -81,6 +81,23 @@ public Mono executeParameterized( ExecuteActionDTO executeActionDTO, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) { + return executeParameterizedWithFlags( + connection, executeActionDTO, datasourceConfiguration, actionConfiguration, null); + } + + @Override + public Mono trigger( + Void connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + return triggerWithFlags(connection, datasourceConfiguration, request, null); + } + + @Override + public Mono executeParameterizedWithFlags( + Void connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": executeParameterized() called for GoogleSheets plugin."); boolean smartJsonSubstitution; @@ -133,13 +150,14 @@ public Mono executeParameterized( prepareConfigurationsForExecution(executeActionDTO, actionConfiguration, datasourceConfiguration); - return this.executeCommon(connection, datasourceConfiguration, actionConfiguration); + return this.executeCommon(connection, datasourceConfiguration, actionConfiguration, featureFlagMap); } public Mono executeCommon( Void connection, DatasourceConfiguration datasourceConfiguration, - ActionConfiguration actionConfiguration) { + ActionConfiguration actionConfiguration, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": executeCommon() called for GoogleSheets plugin."); // Initializing object for error condition @@ -185,7 +203,7 @@ public Mono executeCommon( // method .flatMap(res -> { return executionMethod - .getExecutionClient(client, methodConfig) + .getExecutionClientWithFlags(client, methodConfig, featureFlagMap) .headers(headers -> headers.set( "Authorization", "Bearer " @@ -319,8 +337,11 @@ public Object substituteValueInInput( } @Override - public Mono trigger( - Void connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + public Mono triggerWithFlags( + Void connection, + DatasourceConfiguration datasourceConfiguration, + TriggerRequestDTO request, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": trigger() called for GoogleSheets plugin."); final TriggerMethod triggerMethod = GoogleSheetsMethodStrategy.getTriggerMethod(request, objectMapper); MethodConfig methodConfig = new MethodConfig(request); @@ -343,7 +364,7 @@ public Mono trigger( validateAndGetUserAuthorizedSheetIds(datasourceConfiguration, methodConfig); return triggerMethod - .getTriggerClient(client, methodConfig) + .getTriggerClientWithFlags(client, methodConfig, featureFlagMap) .headers(headers -> headers.set( "Authorization", "Bearer " + oauth2.getAuthenticationResponse().getToken())) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java index ace596c38c93..a983e279d1eb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java @@ -9,6 +9,7 @@ import com.appsmith.server.helpers.PluginExecutorHelper; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.apache.commons.lang3.StringUtils; @@ -28,18 +29,21 @@ public class PluginTriggerSolutionCEImpl implements PluginTriggerSolutionCE { private final PluginRepository pluginRepository; private final ConfigService configService; private final TenantService tenantService; + private final FeatureFlagService featureFlagService; public PluginTriggerSolutionCEImpl( DatasourceTriggerSolution datasourceTriggerSolution, PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService) { + TenantService tenantService, + FeatureFlagService featureFlagService) { this.datasourceTriggerSolution = datasourceTriggerSolution; this.pluginExecutorHelper = pluginExecutorHelper; this.pluginRepository = pluginRepository; this.configService = configService; this.tenantService = tenantService; + this.featureFlagService = featureFlagService; } /** @@ -74,6 +78,11 @@ public Mono trigger( Mono pluginExecutorMono = pluginMono.flatMap(plugin -> pluginExecutorHelper.getPluginExecutor(Mono.just(plugin))); + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Map featureFlagMap = + featureFlagService.getCachedTenantFeatureFlags().getFeatures(); + /* * Since there is no datasource provided, we are passing the Datasource Context connection and datasourceConfiguration as null. * We will leave the execution to respective plugin executor. @@ -83,8 +92,8 @@ public Mono trigger( PluginExecutor pluginExecutor = pair.getT2(); setHeadersToTriggerRequest(plugin, httpHeaders, triggerRequestDTO); return setTenantAndInstanceId(triggerRequestDTO) - .flatMap(updatedTriggerRequestDTO -> - ((PluginExecutor) pluginExecutor).trigger(null, null, updatedTriggerRequestDTO)); + .flatMap(updatedTriggerRequestDTO -> ((PluginExecutor) pluginExecutor) + .triggerWithFlags(null, null, updatedTriggerRequestDTO, featureFlagMap)); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java index f40ff60094d9..373235b5e09d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java @@ -3,6 +3,7 @@ import com.appsmith.server.helpers.PluginExecutorHelper; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.springframework.stereotype.Component; @@ -14,7 +15,14 @@ public PluginTriggerSolutionImpl( PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService) { - super(datasourceTriggerSolution, pluginExecutorHelper, pluginRepository, configService, tenantService); + TenantService tenantService, + FeatureFlagService featureFlagService) { + super( + datasourceTriggerSolution, + pluginExecutorHelper, + pluginRepository, + configService, + tenantService, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java index 1412bd1b6e70..6f3413f55d94 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java @@ -13,6 +13,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ce.ActionExecutionSolutionCEImpl; @@ -42,7 +43,8 @@ public ActionExecutionSolutionImpl( ConfigService configService, TenantService tenantService, CommonConfig commonConfig, - ActionExecutionSolutionHelper actionExecutionSolutionHelper) { + ActionExecutionSolutionHelper actionExecutionSolutionHelper, + FeatureFlagService featureFlagService) { super( newActionService, actionPermission, @@ -63,6 +65,7 @@ public ActionExecutionSolutionImpl( configService, tenantService, commonConfig, - actionExecutionSolutionHelper); + actionExecutionSolutionHelper, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java index 3993270da9db..a892502e7ffb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ce.DatasourceTriggerSolutionCEImpl; import lombok.extern.slf4j.Slf4j; @@ -28,7 +29,8 @@ public DatasourceTriggerSolutionImpl( DatasourcePermission datasourcePermission, EnvironmentPermission environmentPermission, ConfigService configService, - TenantService tenantService) { + TenantService tenantService, + FeatureFlagService featureFlagService) { super( datasourceService, datasourceStorageService, @@ -40,6 +42,7 @@ public DatasourceTriggerSolutionImpl( datasourcePermission, environmentPermission, configService, - tenantService); + tenantService, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 794d24af0b98..3ced1a0a3978 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -45,6 +45,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; @@ -73,6 +74,7 @@ import java.time.Duration; import java.time.Instant; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -122,6 +124,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE private final TenantService tenantService; private final ActionExecutionSolutionHelper actionExecutionSolutionHelper; private final CommonConfig commonConfig; + private final FeatureFlagService featureFlagService; static final String PARAM_KEY_REGEX = "^k\\d+$"; static final String BLOB_KEY_REGEX = @@ -150,7 +153,8 @@ public ActionExecutionSolutionCEImpl( ConfigService configService, TenantService tenantService, CommonConfig commonConfig, - ActionExecutionSolutionHelper actionExecutionSolutionHelper) { + ActionExecutionSolutionHelper actionExecutionSolutionHelper, + FeatureFlagService featureFlagService) { this.newActionService = newActionService; this.actionPermission = actionPermission; this.observationRegistry = observationRegistry; @@ -171,6 +175,7 @@ public ActionExecutionSolutionCEImpl( this.tenantService = tenantService; this.commonConfig = commonConfig; this.actionExecutionSolutionHelper = actionExecutionSolutionHelper; + this.featureFlagService = featureFlagService; this.patternList.add(Pattern.compile(PARAM_KEY_REGEX)); this.patternList.add(Pattern.compile(BLOB_KEY_REGEX)); @@ -726,13 +731,20 @@ protected Mono verifyDatasourceAndMakeRequest( // Now that we have the context (connection details), execute the action. Instant requestedAt = Instant.now(); + Map features = featureFlagService.getCachedTenantFeatureFlags() != null + ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + : Collections.emptyMap(); + + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed return ((PluginExecutor) pluginExecutor) - .executeParameterizedWithMetrics( + .executeParameterizedWithMetricsAndFlags( resourceContext.getConnection(), executeActionDTO, datasourceStorage1.getDatasourceConfiguration(), actionDTO.getActionConfiguration(), - observationRegistry) + observationRegistry, + features) .map(actionExecutionResult -> { ActionExecutionRequest actionExecutionRequest = actionExecutionResult.getRequest(); if (actionExecutionRequest == null) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java index 374264fdaf8d..c4a571037d27 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java @@ -17,6 +17,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.DatasourceStructureSolution; @@ -27,6 +28,7 @@ import reactor.util.function.Tuple2; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -53,6 +55,7 @@ public class DatasourceTriggerSolutionCEImpl implements DatasourceTriggerSolutio private final EnvironmentPermission environmentPermission; private final ConfigService configService; private final TenantService tenantService; + private final FeatureFlagService featureFlagService; public Mono trigger( String datasourceId, String environmentId, TriggerRequestDTO triggerRequestDTO) { @@ -104,6 +107,12 @@ public Mono trigger( final Plugin plugin = tuple.getT2(); final PluginExecutor pluginExecutor = tuple.getT3(); + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Map featureFlagMap = featureFlagService.getCachedTenantFeatureFlags() != null + ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + : Collections.emptyMap(); + return datasourceContextService .getDatasourceContext(datasourceStorage, plugin) // Now that we have the context (connection details), execute the action. @@ -111,10 +120,11 @@ public Mono trigger( // However the context comes from evaluated datasource. .flatMap(resourceContext -> setTenantAndInstanceId(triggerRequestDTO) .flatMap(updatedTriggerRequestDTO -> ((PluginExecutor) pluginExecutor) - .trigger( + .triggerWithFlags( resourceContext.getConnection(), datasourceStorage.getDatasourceConfiguration(), - updatedTriggerRequestDTO))); + updatedTriggerRequestDTO, + featureFlagMap))); }); // If the plugin hasn't implemented the trigger function, go for the default implementation diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java index 603142af9435..ff664b5ee37c 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java @@ -24,6 +24,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; @@ -136,6 +137,9 @@ class ActionExecutionSolutionCEImplTest { @SpyBean ActionExecutionSolutionHelper actionExecutionSolutionHelper; + @SpyBean + FeatureFlagService featureFlagService; + @Autowired EnvironmentPermission environmentPermission; @@ -167,7 +171,8 @@ public void beforeEach() { configService, tenantService, commonConfig, - actionExecutionSolutionHelper); + actionExecutionSolutionHelper, + featureFlagService); ObservationRegistry.ObservationConfig mockObservationConfig = Mockito.mock(ObservationRegistry.ObservationConfig.class); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java index cd2fe3a498aa..306012b752bc 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java @@ -327,6 +327,8 @@ private Mono executeAction( Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.just(mockResult)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.just(mockResult)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -527,6 +529,8 @@ public void testActionExecuteErrorResponse() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(pluginException)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(pluginException)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -584,6 +588,8 @@ public void testActionExecuteNullPaginationParameters() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(pluginException)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(pluginException)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -635,6 +641,9 @@ public void testActionExecuteSecondaryStaleConnection() { Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(new StaleConnectionException())) .thenReturn(Mono.error(new StaleConnectionException())); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(new StaleConnectionException())) + .thenReturn(Mono.error(new StaleConnectionException())); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -686,6 +695,8 @@ public void testActionExecuteTimeout() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenAnswer(x -> Mono.delay(Duration.ofMillis(1000)).ofType(ActionExecutionResult.class)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenAnswer(x -> Mono.delay(Duration.ofMillis(1000)).ofType(ActionExecutionResult.class)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -716,8 +727,9 @@ public void checkRecoveryFromStaleConnections() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) - .thenThrow(new StaleConnectionException()) - .thenReturn(Mono.just(mockResult)); + .thenThrow(new StaleConnectionException()); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenThrow(new StaleConnectionException()); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.when(pluginExecutor.getHintMessages(any(), any())) .thenReturn(Mono.zip(Mono.just(new HashSet<>()), Mono.just(new HashSet<>()))); From 8a1a287f5f2f3eb32f4498003507969ba6c224a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Csneha122=E2=80=9D?= <β€œsneha@appsmith.com”> Date: Thu, 28 Nov 2024 15:31:04 +0530 Subject: [PATCH 06/11] chore: action execution solution test fixed (#37793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Failing server unit test fixed, This test started failing due to changes in this PR: https://github.com/appsmithorg/appsmith/pull/37776, for some reason it did not show up on this Pr in failed test cases Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ /ok-to-test tags="@tag.IconButton" > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: f915b4fd8ac67fcbaaf9b0427ee4cb2296ce4d0e > Cypress dashboard. > Tags: `@tag.IconButton` > Spec: >
Thu, 28 Nov 2024 09:59:28 UTC Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No - **Bug Fixes** - Improved error handling for stale connections during action execution, allowing the system to recover and continue executing actions after an initial failure. Co-authored-by: β€œsneha122” <β€œsneha@appsmith.com”> --- .../server/solutions/ce/ActionExecutionSolutionCETest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java index 306012b752bc..e8bb6bc39db5 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java @@ -727,9 +727,11 @@ public void checkRecoveryFromStaleConnections() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) - .thenThrow(new StaleConnectionException()); + .thenThrow(new StaleConnectionException()) + .thenReturn(Mono.just(mockResult)); Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) - .thenThrow(new StaleConnectionException()); + .thenThrow(new StaleConnectionException()) + .thenReturn(Mono.just(mockResult)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.when(pluginExecutor.getHintMessages(any(), any())) .thenReturn(Mono.zip(Mono.just(new HashSet<>()), Mono.just(new HashSet<>()))); From a8e3d71a9ebe51ec0c1717c5c2651d8192a04941 Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Tue, 3 Dec 2024 14:10:32 +0530 Subject: [PATCH 07/11] fix: Broken UI on JS module instance in the side by side view mode (#37909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Fixing the Broken UI on JS module instance in the side by side view mode. Fixes # ## Automation /ok-to-test tags="@tag.IDE" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: bc011f06fa69836315e61986ce28d6d1ef88e0e5 > Cypress dashboard. > Tags: `@tag.IDE` > Spec: >
Tue, 03 Dec 2024 08:32:26 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Enhanced flexibility of the dropdown selector in the JS Function Run component by removing the minimum width constraint. - **Bug Fixes** - Adjusted layout to improve the visual adaptability of the dropdown selector based on its content. --- .../JSEditor/JSEditorToolbar/components/old/JSFunctionRun.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/client/src/pages/Editor/JSEditor/JSEditorToolbar/components/old/JSFunctionRun.tsx b/app/client/src/pages/Editor/JSEditor/JSEditorToolbar/components/old/JSFunctionRun.tsx index 8567f0d734c9..cbbc13b7afdf 100644 --- a/app/client/src/pages/Editor/JSEditor/JSEditorToolbar/components/old/JSFunctionRun.tsx +++ b/app/client/src/pages/Editor/JSEditor/JSEditorToolbar/components/old/JSFunctionRun.tsx @@ -25,10 +25,6 @@ export interface DropdownWithCTAWrapperProps { const DropdownWithCTAWrapper = styled.div` display: flex; gap: var(--ads-v2-spaces-3); - - .rc-select-selector { - min-width: unset; - } `; const OptionWrapper = styled.div` From 1edecf1afd3ff525f4dd7501bfbbc75855b2808f Mon Sep 17 00:00:00 2001 From: Rudraprasad Das Date: Wed, 4 Dec 2024 22:13:31 +0800 Subject: [PATCH 08/11] fix: fixing usage pulse for anon user (#37940) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description - For usage pulse we need pageId - URL contains basePageId - basePageId needs to be converted to pageId - The conversion needs application data to be populated into redux - The PR adds a wait for application to initialise first before sending the usage pulse Fixes [37904](https://github.com/appsmithorg/appsmith/issues/37904) ## Automation /ok-to-test tags="@tag.All" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: b4c4df19b3dbea128ca63f243cdfbb14c01aa33f > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Wed, 04 Dec 2024 11:40:43 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Enhanced user navigation tracking with improved handling of route changes. - Introduced a new function for managing user activity tracking, improving clarity and control flow. - **Bug Fixes** - Improved error handling during route changes to ensure proper logging. - **Refactor** - Restructured user-related sagas for better organization and separation of concerns. --- app/client/src/ce/sagas/NavigationSagas.ts | 11 ++++++-- app/client/src/ce/sagas/userSagas.tsx | 30 +++++++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/app/client/src/ce/sagas/NavigationSagas.ts b/app/client/src/ce/sagas/NavigationSagas.ts index f84cd79091cd..dff86d7d0890 100644 --- a/app/client/src/ce/sagas/NavigationSagas.ts +++ b/app/client/src/ce/sagas/NavigationSagas.ts @@ -1,10 +1,13 @@ -import { fork, put, select, call } from "redux-saga/effects"; +import { fork, put, select, call, take } from "redux-saga/effects"; import type { RouteChangeActionPayload } from "actions/focusHistoryActions"; import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity"; import log from "loglevel"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { getRecentEntityIds } from "selectors/globalSearchSelectors"; -import type { ReduxAction } from "ee/constants/ReduxActionConstants"; +import { + ReduxActionTypes, + type ReduxAction, +} from "ee/constants/ReduxActionConstants"; import { getCurrentThemeDetails } from "selectors/themeSelectors"; import type { BackgroundTheme } from "sagas/ThemeSaga"; import { changeAppBackground } from "sagas/ThemeSaga"; @@ -86,6 +89,10 @@ function* clearErrors() { } function* watchForTrackableUrl(payload: RouteChangeActionPayload) { + yield take([ + ReduxActionTypes.INITIALIZE_EDITOR_SUCCESS, + ReduxActionTypes.INITIALIZE_PAGE_VIEWER_SUCCESS, + ]); const oldPathname = payload.prevLocation.pathname; const newPathname = payload.location.pathname; const isOldPathTrackable: boolean = yield call( diff --git a/app/client/src/ce/sagas/userSagas.tsx b/app/client/src/ce/sagas/userSagas.tsx index 132341739bb7..34e229fea2c5 100644 --- a/app/client/src/ce/sagas/userSagas.tsx +++ b/app/client/src/ce/sagas/userSagas.tsx @@ -145,15 +145,11 @@ function* initTrackers(currentUser: User) { } } -export function* runUserSideEffectsSaga() { +function* restartUserTracking() { const currentUser: User = yield select(getCurrentUser); const { enableTelemetry } = currentUser; const isAirgappedInstance = isAirgapped(); - if (enableTelemetry) { - yield fork(initTrackers, currentUser); - } - const isFFFetched: boolean = yield select(getFeatureFlagsFetched); if (!isFFFetched) { @@ -169,13 +165,33 @@ export function* runUserSideEffectsSaga() { if (!isAirgappedInstance) { // We need to stop and start tracking activity to ensure that the tracking from previous session is not carried forward - UsagePulse.stopTrackingActivity(); - UsagePulse.startTrackingActivity( + yield call(UsagePulse.stopTrackingActivity); + + if (currentUser?.isAnonymous) { + yield take([ + ReduxActionTypes.INITIALIZE_EDITOR_SUCCESS, + ReduxActionTypes.INITIALIZE_PAGE_VIEWER_SUCCESS, + ]); + } + + yield call( + UsagePulse.startTrackingActivity, enableTelemetry && getAppsmithConfigs().segment.enabled, currentUser?.isAnonymous ?? false, isFreeLicense, ); } +} + +export function* runUserSideEffectsSaga() { + const currentUser: User = yield select(getCurrentUser); + const { enableTelemetry } = currentUser; + + if (enableTelemetry) { + yield fork(initTrackers, currentUser); + } + + yield fork(restartUserTracking); if (currentUser.emptyInstance) { history.replace(SETUP); From 299ce06f54e3d7435110cc4c4950542e48657e01 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Mon, 9 Dec 2024 14:03:09 +0530 Subject: [PATCH 09/11] fix: Only updating the required fields in User while generating usage pulse to avoid overwriting default fields. (#38030) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /test all ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 9f3eebbb4b55da337e6bcb3d80c1bd8c6fbf8e96 > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Mon, 09 Dec 2024 08:27:39 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced methods to update user records directly by ID, enhancing user management capabilities. - Added functionality to update user information without permission checks for administrative purposes. - **Bug Fixes** - Improved error handling for user updates, ensuring robustness in user management operations. - **Documentation** - Updated documentation to reflect new methods and their functionalities in user services. --- .../repositories/ce/CustomUserRepositoryCE.java | 3 +++ .../ce/CustomUserRepositoryCEImpl.java | 11 +++++++++++ .../services/ce/UsagePulseServiceCEImpl.java | 16 ++++++++++------ .../server/services/ce/UserServiceCE.java | 3 +++ .../server/services/ce/UserServiceCEImpl.java | 10 ++++++++++ 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java index d071b5e04e7e..6ceef7aed4a5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCE.java @@ -3,6 +3,7 @@ import com.appsmith.server.acl.AclPermission; import com.appsmith.server.domains.User; import com.appsmith.server.repositories.AppsmithRepository; +import org.springframework.data.mongodb.core.query.UpdateDefinition; import reactor.core.publisher.Mono; public interface CustomUserRepositoryCE extends AppsmithRepository { @@ -12,4 +13,6 @@ public interface CustomUserRepositoryCE extends AppsmithRepository { Mono findByEmailAndTenantId(String email, String tenantId); Mono isUsersEmpty(); + + Mono updateById(String id, UpdateDefinition updateObj); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java index 8508431a7257..b09ac27cc259 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomUserRepositoryCEImpl.java @@ -3,11 +3,14 @@ import com.appsmith.server.acl.AclPermission; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.User; +import com.appsmith.server.exceptions.AppsmithError; +import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.ce.bridge.Bridge; import com.appsmith.server.helpers.ce.bridge.BridgeQuery; import com.appsmith.server.projections.IdOnly; import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.query.UpdateDefinition; import reactor.core.publisher.Mono; import java.util.HashSet; @@ -50,4 +53,12 @@ protected Set getSystemGeneratedUserEmails() { systemGeneratedEmails.add(FieldName.ANONYMOUS_USER); return systemGeneratedEmails; } + + @Override + public Mono updateById(String id, UpdateDefinition updateObj) { + if (id == null) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID)); + } + return queryBuilder().byId(id).updateFirst(updateObj); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java index 1d15be8c9007..55027b06933b 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UsagePulseServiceCEImpl.java @@ -7,6 +7,8 @@ import com.appsmith.server.dtos.UsagePulseDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; +import com.appsmith.server.helpers.ce.bridge.Bridge; +import com.appsmith.server.helpers.ce.bridge.BridgeUpdate; import com.appsmith.server.repositories.UsagePulseRepository; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.SessionUserService; @@ -83,19 +85,21 @@ public Mono createPulse(UsagePulseDTO usagePulseDTO) { return save(usagePulse); } usagePulse.setIsAnonymousUser(false); - User updateUser = new User(); + BridgeUpdate updateUserObj = Bridge.update(); + String hashedEmail = user.getHashedEmail(); if (StringUtils.isEmpty(hashedEmail)) { hashedEmail = DigestUtils.sha256Hex(user.getEmail()); // Hashed user email is stored to user for future mapping of user and pulses - updateUser.setHashedEmail(hashedEmail); + updateUserObj.set(User.Fields.hashedEmail, hashedEmail); } usagePulse.setUser(hashedEmail); - updateUser.setLastActiveAt(Instant.now()); - // Avoid updating policies - updateUser.setPolicies(null); - return userService.updateWithoutPermission(user.getId(), updateUser).then(save(usagePulse)); + updateUserObj.set(User.Fields.lastActiveAt, Instant.now()); + + return userService + .updateWithoutPermission(user.getId(), updateUserObj) + .then(save(usagePulse)); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java index 3c489065891f..2bdb85f67803 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCE.java @@ -8,6 +8,7 @@ import com.appsmith.server.dtos.UserSignupDTO; import com.appsmith.server.dtos.UserUpdateDTO; import com.appsmith.server.services.CrudService; +import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -30,6 +31,8 @@ public interface UserServiceCE extends CrudService { Mono userCreate(User user, boolean isAdminUser); + Mono updateWithoutPermission(String id, UpdateDefinition updateObj); + Mono updateCurrentUser(UserUpdateDTO updates, ServerWebExchange exchange); Mono isUsersEmpty(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java index 9cede7c2f620..35d24c352aa4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/UserServiceCEImpl.java @@ -43,6 +43,7 @@ import org.apache.hc.core5.http.message.BasicNameValuePair; import org.apache.hc.core5.net.WWWFormCodec; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.query.UpdateDefinition; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; @@ -568,6 +569,15 @@ public Mono updateWithoutPermission(String id, User update) { return userFromRepository.flatMap(existingUser -> this.update(existingUser, update)); } + @Override + public Mono updateWithoutPermission(String id, UpdateDefinition updateObj) { + Mono userFromRepository = repository + .findById(id) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.USER, id))); + + return userFromRepository.flatMap(existingUser -> repository.updateById(id, updateObj)); + } + private Mono update(User existingUser, User userUpdate) { // The password is being updated. Hash it first and then store it From ae9e0069e29d5cfd430f6e9f0e280d6fae180fb0 Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Wed, 11 Dec 2024 18:40:16 +0530 Subject: [PATCH 10/11] fixing the client build failure on prod --- .../components/DatasourceTab/Datasource.tsx | 5 +++++ .../DatasourceTab/DatasourceInfo.tsx | 4 ++++ .../DatasourceTab/DatasourceSelector/index.tsx | 18 +++++++++--------- .../DatasourceTab/DatasourceTables.tsx | 4 ++++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/Datasource.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/Datasource.tsx index 0771efb25e93..1162f39978a0 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/Datasource.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/Datasource.tsx @@ -25,6 +25,7 @@ import { BOTTOMBAR_HEIGHT } from "./constants"; import { useEditorType } from "ee/hooks"; import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; import DatasourceInfo from "./DatasourceInfo"; +import { getPlugin } from "ee/selectors/entitiesSelector"; interface Props { datasourceId: string; @@ -45,6 +46,8 @@ const Datasource = (props: Props) => { getPluginIdFromDatasourceId(state, props.datasourceId), ); + const plugin = useSelector((state) => getPlugin(state, pluginId || "")); + const editorType = useEditorType(location.pathname); const { parentEntityId } = useParentEntityInfo(editorType); @@ -143,6 +146,7 @@ const Datasource = (props: Props) => { { datasourceId={props.datasourceId} datasourceName={props.datasourceName} datasourceStructure={datasourceStructure} + plugin={plugin} selectedTable={selectedTable} setSelectedTable={setSelectedTable} /> diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx index e671e70d4afc..acfa33571870 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceInfo.tsx @@ -10,16 +10,19 @@ import { getQueryParams } from "utils/URLUtils"; import history from "utils/history"; import { useEditorType } from "ee/hooks"; import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; +import type { Plugin } from "api/PluginApi"; interface Props { datasourceId: string; datasourceName: string; showEditButton: boolean; + plugin?: Plugin; } const DatasourceInfo = ({ datasourceId, datasourceName, + plugin, showEditButton, }: Props) => { const editorType = useEditorType(location.pathname); @@ -50,6 +53,7 @@ const DatasourceInfo = ({ {showEditButton && ( diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceSelector/index.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceSelector/index.tsx index 6f3ef2f510f1..252643232aaf 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceSelector/index.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceSelector/index.tsx @@ -1,6 +1,5 @@ import React from "react"; -import { UIComponentTypes } from "api/PluginApi"; -import { usePluginActionContext } from "PluginActionEditor/PluginActionContext"; +import { UIComponentTypes, type Plugin } from "api/PluginApi"; import ApiDatasourceSelector from "./ApiDatasourceSelector"; import QueryDatasourceSelector from "./QueryDatasourceSelector"; import { @@ -16,16 +15,17 @@ const API_FORM_COMPONENTS = [ export interface DatasourceProps { datasourceId: string; datasourceName: string; + plugin?: Plugin; } const DatasourceSelector = (props: DatasourceProps) => { - const { plugin } = usePluginActionContext(); - - return API_FORM_COMPONENTS.includes(plugin.uiComponent) ? ( - - ) : ( - - ); + return props.plugin ? ( + API_FORM_COMPONENTS.includes(props.plugin.uiComponent) ? ( + + ) : ( + + ) + ) : null; }; export default DatasourceSelector; diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTables.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTables.tsx index 1664ff7667aa..ef23751816ef 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTables.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/components/DatasourceTab/DatasourceTables.tsx @@ -9,12 +9,14 @@ import { refreshDatasourceStructure } from "actions/datasourceActions"; import { useDispatch } from "react-redux"; import { SchemaTableContainer } from "./styles"; import DatasourceInfo from "./DatasourceInfo"; +import type { Plugin } from "api/PluginApi"; interface Props { datasourceId: string; datasourceName: string; currentActionId: string; datasourceStructure: DatasourceStructure; + plugin?: Plugin; setSelectedTable: (table: string) => void; selectedTable: string | undefined; } @@ -24,6 +26,7 @@ const DatasourceTables = ({ datasourceId, datasourceName, datasourceStructure, + plugin, selectedTable, setSelectedTable, }: Props) => { @@ -56,6 +59,7 @@ const DatasourceTables = ({