Skip to content

Commit

Permalink
feat: paragon frontend ds creation implementation added (#38456)
Browse files Browse the repository at this point in the history
## Description

This PR adds CE changes for the paragon integrations, with this whenever
anybody is using CE version, paragon integrations will be visible but
once they click on it, it will ask for them to put in email id and
request access.

It's counterpart EE PR handles the paragon integration creation and
authorisation in appsmith.

EE PR: appsmithorg/appsmith-ee#5859
EE PR which has both CE and EE changes to ensure all things are working
smoothly: appsmithorg/appsmith-ee#5866


Fixes #`38406`  
_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

/ok-to-test tags="@tag.Datasource"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12627633263>
> Commit: 9c1e06b
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12627633263&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Datasource`
> Spec:
> <hr>Mon, 06 Jan 2025 07:10:57 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
  - Added support for External SaaS datasources and plugins.
- Introduced new actions and configurations for External SaaS
integration.

- **Refactor**
  - Restructured datasource-related sagas and import paths.
  - Updated selectors and constants to support new plugin type.

- **Code Improvements**
  - Enhanced datasource management and integration capabilities.
  - Improved modularity of saga functions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: “sneha122” <“sneha@appsmith.com”>
  • Loading branch information
sneha122 and “sneha122” authored Jan 7, 2025
1 parent a4163f8 commit 3626b93
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 156 deletions.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/client/src/ce/sagas/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import autoLayoutDraggingSagas from "sagas/CanvasSagas/AutoLayoutDraggingSagas";
import draggingCanvasSagas from "sagas/CanvasSagas/DraggingCanvasSagas";
import selectionCanvasSagas from "sagas/CanvasSagas/SelectionCanvasSagas";
import curlImportSagas from "sagas/CurlImportSagas";
import { watchDatasourcesSagas } from "sagas/DatasourcesSagas";
import { watchDatasourcesSagas } from "ee/sagas/DatasourcesSagas";
import debuggerSagas from "sagas/DebuggerSagas";
import editorContextSagas from "sagas/editorContextSagas";
import errorSagas from "sagas/ErrorSagas";
Expand Down
3 changes: 2 additions & 1 deletion app/client/src/ce/selectors/entitiesSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export const getDatasourcesGroupedByPluginCategory = createSelector(

if (
plugin.type === PluginType.SAAS ||
plugin.type === PluginType.REMOTE
plugin.type === PluginType.REMOTE ||
plugin.type === PluginType.EXTERNAL_SAAS
) {
return PluginCategory.SAAS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export const defaultActionSettings: Record<PluginType, any> = {
[PluginType.JS]: [],
[PluginType.AI]: saasActionSettingsConfig,
[PluginType.INTERNAL]: saasActionSettingsConfig,
[PluginType.EXTERNAL_SAAS]: saasActionSettingsConfig,
};

// TODO: Fix this the next time the file is edited
Expand All @@ -189,6 +190,7 @@ export const defaultActionEditorConfigs: Record<PluginType, any> = {
[PluginType.JS]: [],
[PluginType.AI]: [],
[PluginType.INTERNAL]: [],
[PluginType.EXTERNAL_SAAS]: [],
};

export const defaultActionDependenciesConfig: Record<
Expand All @@ -202,6 +204,7 @@ export const defaultActionDependenciesConfig: Record<
[PluginType.JS]: {},
[PluginType.AI]: {},
[PluginType.INTERNAL]: {},
[PluginType.EXTERNAL_SAAS]: {},
};

export const defaultDatasourceFormButtonConfig: Record<PluginType, string[]> = {
Expand All @@ -212,4 +215,5 @@ export const defaultDatasourceFormButtonConfig: Record<PluginType, string[]> = {
[PluginType.JS]: [],
[PluginType.AI]: apiActionDatasourceFormButtonConfig.AI,
[PluginType.INTERNAL]: [],
[PluginType.EXTERNAL_SAAS]: apiActionDatasourceFormButtonConfig.EXTERNAL_SAAS,
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export default {
SAAS: ["CANCEL", "SAVE_AND_AUTHORIZE"],
REMOTE: ["CANCEL", "SAVE"],
AI: ["TEST", "CANCEL", "SAVE"],
EXTERNAL_SAAS: ["CANCEL", "SAVE_AND_AUTHORIZE"],
};
140 changes: 140 additions & 0 deletions app/client/src/ee/sagas/DatasourcesSagas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
export { createOrUpdateDataSourceWithAction } from "ce/sagas/DatasourcesSagas";
import {
ReduxActionErrorTypes,
ReduxActionTypes,
ReduxFormActionTypes,
} from "ee/constants/ReduxActionConstants";
import { all, takeEvery, takeLatest } from "redux-saga/effects";
import {
addAndFetchDatasourceStructureSaga,
addMockDbToDatasources,
changeDatasourceSaga,
createDatasourceFromFormSaga,
datasourceDiscardActionSaga,
deleteDatasourceSaga,
executeDatasourceQuerySaga,
fetchDatasourcesSaga,
fetchDatasourceStructureSaga,
fetchGsheetColumns,
fetchGsheetSheets,
fetchGsheetSpreadhsheets,
fetchMockDatasourcesSaga,
filePickerActionCallbackSaga,
formValueChangeSaga,
getOAuthAccessTokenSaga,
handleDatasourceNameChangeFailureSaga,
handleFetchDatasourceStructureOnLoad,
initializeFormWithDefaults,
loadFilePickerSaga,
redirectAuthorizationCodeSaga,
refreshDatasourceStructure,
setDatasourceViewModeSaga,
storeAsDatasourceSaga,
switchDatasourceSaga,
testDatasourceSaga,
updateDatasourceAuthStateSaga,
updateDatasourceNameSaga,
updateDatasourceSaga,
updateDatasourceSuccessSaga,
createTempDatasourceFromFormSaga as CE_createTempDatasourceFromFormSaga,
} from "ce/sagas/DatasourcesSagas";

export function* watchDatasourcesSagas() {
yield all([
takeEvery(ReduxActionTypes.FETCH_DATASOURCES_INIT, fetchDatasourcesSaga),
takeEvery(
ReduxActionTypes.FETCH_MOCK_DATASOURCES_INIT,
fetchMockDatasourcesSaga,
),
takeEvery(
ReduxActionTypes.ADD_MOCK_DATASOURCES_INIT,
addMockDbToDatasources,
),
takeEvery(
ReduxActionTypes.CREATE_DATASOURCE_FROM_FORM_INIT,
createDatasourceFromFormSaga,
),
takeEvery(
ReduxActionTypes.CREATE_TEMP_DATASOURCE_FROM_FORM_SUCCESS,
CE_createTempDatasourceFromFormSaga,
),
takeEvery(ReduxActionTypes.UPDATE_DATASOURCE_INIT, updateDatasourceSaga),
takeEvery(
ReduxActionTypes.UPDATE_DATASOURCE_NAME,
updateDatasourceNameSaga,
),
takeEvery(
ReduxActionErrorTypes.UPDATE_DATASOURCE_NAME_ERROR,
handleDatasourceNameChangeFailureSaga,
),
takeEvery(ReduxActionTypes.TEST_DATASOURCE_INIT, testDatasourceSaga),
takeEvery(ReduxActionTypes.DELETE_DATASOURCE_INIT, deleteDatasourceSaga),
takeEvery(ReduxActionTypes.CHANGE_DATASOURCE, changeDatasourceSaga),
takeLatest(ReduxActionTypes.SWITCH_DATASOURCE, switchDatasourceSaga),
takeEvery(ReduxActionTypes.STORE_AS_DATASOURCE_INIT, storeAsDatasourceSaga),
takeEvery(
ReduxActionTypes.UPDATE_DATASOURCE_SUCCESS,
updateDatasourceSuccessSaga,
),
takeEvery(
ReduxActionTypes.REDIRECT_AUTHORIZATION_CODE,
redirectAuthorizationCodeSaga,
),
takeEvery(ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN, getOAuthAccessTokenSaga),
takeEvery(
ReduxActionTypes.FETCH_DATASOURCE_STRUCTURE_INIT,
fetchDatasourceStructureSaga,
),
takeEvery(
ReduxActionTypes.REFRESH_DATASOURCE_STRUCTURE_INIT,
refreshDatasourceStructure,
),
takeEvery(
ReduxActionTypes.EXECUTE_DATASOURCE_QUERY_INIT,
executeDatasourceQuerySaga,
),
takeEvery(
ReduxActionTypes.INITIALIZE_DATASOURCE_FORM_WITH_DEFAULTS,
initializeFormWithDefaults,
),
// Intercepting the redux-form change actionType to update drafts and track change history
takeEvery(ReduxFormActionTypes.VALUE_CHANGE, formValueChangeSaga),
takeEvery(ReduxFormActionTypes.ARRAY_PUSH, formValueChangeSaga),
takeEvery(ReduxFormActionTypes.ARRAY_REMOVE, formValueChangeSaga),
takeEvery(
ReduxActionTypes.FILE_PICKER_CALLBACK_ACTION,
filePickerActionCallbackSaga,
),
takeLatest(
ReduxActionTypes.FETCH_GSHEET_SPREADSHEETS,
fetchGsheetSpreadhsheets,
),
takeLatest(ReduxActionTypes.FETCH_GSHEET_SHEETS, fetchGsheetSheets),
takeLatest(ReduxActionTypes.FETCH_GSHEET_COLUMNS, fetchGsheetColumns),
takeEvery(ReduxActionTypes.LOAD_FILE_PICKER_ACTION, loadFilePickerSaga),
takeEvery(
ReduxActionTypes.UPDATE_DATASOURCE_AUTH_STATE,
updateDatasourceAuthStateSaga,
),
takeEvery(
ReduxActionTypes.DATASOURCE_DISCARD_ACTION,
datasourceDiscardActionSaga,
),
takeEvery(
ReduxActionTypes.ADD_AND_FETCH_MOCK_DATASOURCE_STRUCTURE_INIT,
addAndFetchDatasourceStructureSaga,
),
takeEvery(
ReduxActionTypes.FETCH_DATASOURCES_SUCCESS,
handleFetchDatasourceStructureOnLoad,
),
takeEvery(
ReduxActionTypes.SOFT_REFRESH_DATASOURCE_STRUCTURE,
handleFetchDatasourceStructureOnLoad,
),
takeEvery(
ReduxActionTypes.SET_DATASOURCE_EDITOR_MODE,
setDatasourceViewModeSaga,
),
]);
}
12 changes: 11 additions & 1 deletion app/client/src/entities/Action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum PluginType {
REMOTE = "REMOTE",
AI = "AI",
INTERNAL = "INTERNAL",
EXTERNAL_SAAS = "EXTERNAL_SAAS",
}

export enum PluginPackageName {
Expand Down Expand Up @@ -260,13 +261,22 @@ export interface ActionViewMode {
timeoutInMillisecond?: number;
}

export interface ExternalSaasAction extends BaseAction {
pluginType: PluginType.EXTERNAL_SAAS;
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
actionConfiguration: any;
datasource: StoredDatasource;
}

export type Action =
| ApiAction
| QueryAction
| SaaSAction
| RemoteAction
| AIAction
| InternalAction;
| InternalAction
| ExternalSaasAction;

export enum SlashCommand {
NEW_API,
Expand Down
12 changes: 11 additions & 1 deletion app/client/src/entities/Datasource/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export enum DatasourceConnectionMode {

export interface DatasourceConfiguration {
url: string;
authentication?: DatasourceAuthentication;
authentication?: ExternalSaasDSAuthentication | DatasourceAuthentication;
properties?: Property[];
headers?: Property[];
queryParameters?: Property[];
Expand Down Expand Up @@ -206,3 +206,13 @@ export enum DatasourceStructureContext {
// this does not exist yet, but in case it does in the future.
API_EDITOR = "api-editor",
}

export interface ExternalSaasDSAuthentication extends DatasourceAuthentication {
integrationId: string;
credentialId: string;
integrationType: string;
}

export enum AuthenticationType {
EXTERNAL_SAAS_AUTHENTICATION = "externalSaasAuth",
}
2 changes: 1 addition & 1 deletion app/client/src/entities/JSCollection/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BaseAction } from "../Action";
import type { BaseAction } from "../../entities/Action";
import type { PluginType } from "entities/Action";
import type { LayoutOnLoadActionErrors } from "constants/AppsmithActionConstants/ActionConstants";
import type { ActionParentEntityTypeInterface } from "ee/entities/Engine/actionHelpers";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class ActionPaneNavigationFactory {
case PluginType.DB:
case PluginType.SAAS:
case PluginType.REMOTE:
case PluginType.EXTERNAL_SAAS:
case PluginType.AI:
return new QueryPaneNavigation(entityInfo);
default:
Expand Down
4 changes: 3 additions & 1 deletion app/client/src/pages/Editor/IntegrationEditor/NewApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@ function NewApiScreen(props: Props) {
const API_PLUGINS = plugins.filter((p) =>
!showSaasAPIs
? p.packageName === PluginPackageName.GRAPHQL
: p.type === PluginType.SAAS || p.type === PluginType.REMOTE,
: p.type === PluginType.SAAS ||
p.type === PluginType.REMOTE ||
p.type === PluginType.EXTERNAL_SAAS,
);

return (
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/sagas/WidgetBlueprintSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { toast } from "@appsmith/ads";
import type { LayoutSystemTypes } from "layoutSystems/types";
import { getLayoutSystemType } from "selectors/layoutSystemSelectors";
import type { Action, PluginPackageName } from "../entities/Action";
import { createOrUpdateDataSourceWithAction } from "./DatasourcesSagas";
import { createOrUpdateDataSourceWithAction } from "../ee/sagas/DatasourcesSagas";

function buildView(view: WidgetBlueprint["view"], widgetId: string) {
const children = [];
Expand Down
2 changes: 1 addition & 1 deletion app/client/test/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import userSagas from "ee/sagas/userSagas";
import workspaceSagas from "ee/sagas/WorkspaceSagas";
import { watchActionSagas } from "sagas/ActionSagas";
import layoutUpdateSagas from "sagas/AutoLayoutUpdateSagas";
import { watchDatasourcesSagas } from "sagas/DatasourcesSagas";
import { watchDatasourcesSagas } from "ee/sagas/DatasourcesSagas";
import { watchJSActionSagas } from "ee/sagas/JSActionSagas";
import apiPaneSagas from "../src/sagas/ApiPaneSagas";
import applicationSagas from "ee/sagas/ApplicationSagas";
Expand Down

0 comments on commit 3626b93

Please sign in to comment.