Merge pull request #36337 from appsmithorg/release
16/09 Daily Promotion
This commit is contained in:
commit
d52aa53bb6
|
|
@ -163,7 +163,7 @@
|
||||||
"node-forge": "^1.3.0",
|
"node-forge": "^1.3.0",
|
||||||
"normalizr": "^3.3.0",
|
"normalizr": "^3.3.0",
|
||||||
"object-hash": "^3.0.0",
|
"object-hash": "^3.0.0",
|
||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.3.0",
|
||||||
"popper.js": "^1.15.0",
|
"popper.js": "^1.15.0",
|
||||||
"prismjs": "^1.27.0",
|
"prismjs": "^1.27.0",
|
||||||
"proxy-memoize": "^1.2.0",
|
"proxy-memoize": "^1.2.0",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { IDEToolbar } from "IDE";
|
import { IDEToolbar } from "IDE";
|
||||||
import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
|
import { Button, Menu, MenuContent, MenuTrigger, Tooltip } from "@appsmith/ads";
|
||||||
import { modText } from "utils/helpers";
|
import { modText } from "utils/helpers";
|
||||||
|
import { usePluginActionContext } from "../PluginActionContext";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||||
|
import { runAction } from "../../actions/pluginActionActions";
|
||||||
|
|
||||||
interface PluginActionToolbarProps {
|
interface PluginActionToolbarProps {
|
||||||
runOptions?: React.ReactNode;
|
runOptions?: React.ReactNode;
|
||||||
|
|
@ -10,6 +14,25 @@ interface PluginActionToolbarProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
|
const { action, datasource, plugin } = usePluginActionContext();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const handleRunClick = useCallback(() => {
|
||||||
|
AnalyticsUtil.logEvent("RUN_QUERY_CLICK", {
|
||||||
|
actionName: action.name,
|
||||||
|
actionId: action.id,
|
||||||
|
pluginName: plugin.name,
|
||||||
|
datasourceId: datasource?.id,
|
||||||
|
isMock: datasource?.isMock,
|
||||||
|
});
|
||||||
|
dispatch(runAction(action.id));
|
||||||
|
}, [
|
||||||
|
action.id,
|
||||||
|
action.name,
|
||||||
|
datasource?.id,
|
||||||
|
datasource?.isMock,
|
||||||
|
dispatch,
|
||||||
|
plugin.name,
|
||||||
|
]);
|
||||||
return (
|
return (
|
||||||
<IDEToolbar>
|
<IDEToolbar>
|
||||||
<IDEToolbar.Left>{props.children}</IDEToolbar.Left>
|
<IDEToolbar.Left>{props.children}</IDEToolbar.Left>
|
||||||
|
|
@ -20,7 +43,7 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
placement="topRight"
|
placement="topRight"
|
||||||
showArrow={false}
|
showArrow={false}
|
||||||
>
|
>
|
||||||
<Button kind="primary" size="sm">
|
<Button kind="primary" onClick={handleRunClick} size="sm">
|
||||||
Run
|
Run
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
@ -30,7 +53,7 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
size="sm"
|
size="sm"
|
||||||
startIcon="settings-2-line"
|
startIcon="settings-2-line"
|
||||||
/>
|
/>
|
||||||
<Menu>
|
<Menu key={action.id}>
|
||||||
<MenuTrigger>
|
<MenuTrigger>
|
||||||
<Button
|
<Button
|
||||||
isIconButton
|
isIconButton
|
||||||
|
|
@ -39,7 +62,12 @@ const PluginActionToolbar = (props: PluginActionToolbarProps) => {
|
||||||
startIcon="more-2-fill"
|
startIcon="more-2-fill"
|
||||||
/>
|
/>
|
||||||
</MenuTrigger>
|
</MenuTrigger>
|
||||||
<MenuContent loop style={{ zIndex: 100 }} width="200px">
|
<MenuContent
|
||||||
|
key={action.id}
|
||||||
|
loop
|
||||||
|
style={{ zIndex: 100 }}
|
||||||
|
width="200px"
|
||||||
|
>
|
||||||
{props.menuContent}
|
{props.menuContent}
|
||||||
</MenuContent>
|
</MenuContent>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { PluginActionToolbar } from "PluginActionEditor";
|
import { PluginActionToolbar } from "PluginActionEditor";
|
||||||
import { ConvertToModuleCTA } from "./ConvertToModule";
|
import AppPluginActionMenu from "./PluginActionMoreActions";
|
||||||
|
|
||||||
const AppPluginActionToolbar = () => {
|
const AppPluginActionToolbar = () => {
|
||||||
return <PluginActionToolbar menuContent={<ConvertToModuleCTA />} />;
|
return <PluginActionToolbar menuContent={<AppPluginActionMenu />} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AppPluginActionToolbar;
|
export default AppPluginActionToolbar;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
import React, { useCallback, useMemo, useState } from "react";
|
||||||
|
import {
|
||||||
|
getHasDeleteActionPermission,
|
||||||
|
getHasManageActionPermission,
|
||||||
|
} from "ee/utils/BusinessFeatures/permissionPageHelpers";
|
||||||
|
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||||
|
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
|
||||||
|
import { usePluginActionContext } from "PluginActionEditor";
|
||||||
|
import {
|
||||||
|
MenuItem,
|
||||||
|
MenuSub,
|
||||||
|
MenuSubContent,
|
||||||
|
MenuSubTrigger,
|
||||||
|
} from "@appsmith/ads";
|
||||||
|
import {
|
||||||
|
CONFIRM_CONTEXT_DELETE,
|
||||||
|
CONTEXT_COPY,
|
||||||
|
CONTEXT_DELETE,
|
||||||
|
CONTEXT_MOVE,
|
||||||
|
createMessage,
|
||||||
|
} from "ee/constants/messages";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import {
|
||||||
|
copyActionRequest,
|
||||||
|
deleteAction,
|
||||||
|
moveActionRequest,
|
||||||
|
} from "actions/pluginActionActions";
|
||||||
|
import { getCurrentPageId } from "selectors/editorSelectors";
|
||||||
|
import type { Page } from "entities/Page";
|
||||||
|
import { getPageList } from "ee/selectors/entitiesSelector";
|
||||||
|
import { ConvertToModuleCTA } from "./ConvertToModule";
|
||||||
|
|
||||||
|
const PageMenuItem = (props: {
|
||||||
|
page: Page;
|
||||||
|
onSelect: (id: string) => void;
|
||||||
|
}) => {
|
||||||
|
const handleOnSelect = useCallback(() => {
|
||||||
|
props.onSelect(props.page.pageId);
|
||||||
|
}, [props]);
|
||||||
|
return <MenuItem onSelect={handleOnSelect}>{props.page.pageName}</MenuItem>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Copy = () => {
|
||||||
|
const menuPages = useSelector(getPageList);
|
||||||
|
const { action } = usePluginActionContext();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const copyActionToPage = useCallback(
|
||||||
|
(pageId: string) =>
|
||||||
|
dispatch(
|
||||||
|
copyActionRequest({
|
||||||
|
id: action.id,
|
||||||
|
destinationPageId: pageId,
|
||||||
|
name: action.name,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
[action.id, action.name, dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuSub>
|
||||||
|
<MenuSubTrigger startIcon="duplicate">
|
||||||
|
{createMessage(CONTEXT_COPY)}
|
||||||
|
</MenuSubTrigger>
|
||||||
|
<MenuSubContent>
|
||||||
|
{menuPages.map((page) => {
|
||||||
|
return (
|
||||||
|
<PageMenuItem
|
||||||
|
key={page.basePageId}
|
||||||
|
onSelect={copyActionToPage}
|
||||||
|
page={page}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</MenuSubContent>
|
||||||
|
</MenuSub>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Move = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { action } = usePluginActionContext();
|
||||||
|
|
||||||
|
const currentPageId = useSelector(getCurrentPageId);
|
||||||
|
const allPages = useSelector(getPageList);
|
||||||
|
const menuPages = useMemo(() => {
|
||||||
|
return allPages.filter((page) => page.pageId !== currentPageId);
|
||||||
|
}, [allPages, currentPageId]);
|
||||||
|
|
||||||
|
const moveActionToPage = useCallback(
|
||||||
|
(destinationPageId: string) =>
|
||||||
|
dispatch(
|
||||||
|
moveActionRequest({
|
||||||
|
id: action.id,
|
||||||
|
destinationPageId,
|
||||||
|
originalPageId: currentPageId,
|
||||||
|
name: action.name,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
[dispatch, action.id, action.name, currentPageId],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuSub>
|
||||||
|
<MenuSubTrigger startIcon="swap-horizontal">
|
||||||
|
{createMessage(CONTEXT_MOVE)}
|
||||||
|
</MenuSubTrigger>
|
||||||
|
<MenuSubContent>
|
||||||
|
{menuPages.length > 1 ? (
|
||||||
|
menuPages.map((page) => {
|
||||||
|
return (
|
||||||
|
<PageMenuItem
|
||||||
|
key={page.basePageId}
|
||||||
|
onSelect={moveActionToPage}
|
||||||
|
page={page}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<MenuItem key="no-pages">No pages</MenuItem>
|
||||||
|
)}
|
||||||
|
</MenuSubContent>
|
||||||
|
</MenuSub>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Delete = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const { action } = usePluginActionContext();
|
||||||
|
|
||||||
|
const [confirmDelete, setConfirmDelete] = useState(false);
|
||||||
|
|
||||||
|
const deleteActionFromPage = useCallback(() => {
|
||||||
|
dispatch(deleteAction({ id: action.id, name: action.name }));
|
||||||
|
}, [action.id, action.name, dispatch]);
|
||||||
|
|
||||||
|
const handleSelect = useCallback(() => {
|
||||||
|
confirmDelete ? deleteActionFromPage() : setConfirmDelete(true);
|
||||||
|
}, [confirmDelete, deleteActionFromPage]);
|
||||||
|
|
||||||
|
const menuLabel = confirmDelete
|
||||||
|
? createMessage(CONFIRM_CONTEXT_DELETE)
|
||||||
|
: createMessage(CONTEXT_DELETE);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
className="t--apiFormDeleteBtn error-menuitem"
|
||||||
|
onSelect={handleSelect}
|
||||||
|
startIcon="trash"
|
||||||
|
>
|
||||||
|
{menuLabel}
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppPluginActionMenu = () => {
|
||||||
|
const { action } = usePluginActionContext();
|
||||||
|
|
||||||
|
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
|
||||||
|
const isChangePermitted = getHasManageActionPermission(
|
||||||
|
isFeatureEnabled,
|
||||||
|
action.userPermissions,
|
||||||
|
);
|
||||||
|
const isDeletePermitted = getHasDeleteActionPermission(
|
||||||
|
isFeatureEnabled,
|
||||||
|
action?.userPermissions,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ConvertToModuleCTA />
|
||||||
|
{isChangePermitted && (
|
||||||
|
<>
|
||||||
|
<Copy />
|
||||||
|
<Move />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{isDeletePermitted && <Delete />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppPluginActionMenu;
|
||||||
|
|
@ -13391,7 +13391,7 @@ __metadata:
|
||||||
node-forge: ^1.3.0
|
node-forge: ^1.3.0
|
||||||
normalizr: ^3.3.0
|
normalizr: ^3.3.0
|
||||||
object-hash: ^3.0.0
|
object-hash: ^3.0.0
|
||||||
path-to-regexp: ^6.2.0
|
path-to-regexp: ^6.3.0
|
||||||
pg: ^8.11.3
|
pg: ^8.11.3
|
||||||
plop: ^3.1.1
|
plop: ^3.1.1
|
||||||
popper.js: ^1.15.0
|
popper.js: ^1.15.0
|
||||||
|
|
@ -27112,10 +27112,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"path-to-regexp@npm:^6.2.0":
|
"path-to-regexp@npm:^6.3.0":
|
||||||
version: 6.2.0
|
version: 6.3.0
|
||||||
resolution: "path-to-regexp@npm:6.2.0"
|
resolution: "path-to-regexp@npm:6.3.0"
|
||||||
checksum: a6aca74d2d6e2e7594d812f653cf85e9cb5054d3a8d80f099722a44ef6ad22639b02078e5ea83d11db16321c3e4359e3f1ab0274fa78dad0754a6e53f630b0fc
|
checksum: eca78602e6434a1b6799d511d375ec044e8d7e28f5a48aa5c28d57d8152fb52f3fc62fb1cfc5dfa2198e1f041c2a82ed14043d75740a2fe60e91b5089a153250
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,10 @@ public class DatasourceConfiguration implements AppsmithDomain {
|
||||||
@JsonView({Views.Public.class, FromRequest.class})
|
@JsonView({Views.Public.class, FromRequest.class})
|
||||||
AuthenticationDTO authentication;
|
AuthenticationDTO authentication;
|
||||||
|
|
||||||
|
@JsonView({Views.Public.class, FromRequest.class})
|
||||||
SSHConnection sshProxy;
|
SSHConnection sshProxy;
|
||||||
|
|
||||||
|
@JsonView({Views.Public.class, FromRequest.class})
|
||||||
Boolean sshProxyEnabled;
|
Boolean sshProxyEnabled;
|
||||||
|
|
||||||
@JsonView({Views.Public.class, FromRequest.class, Git.class})
|
@JsonView({Views.Public.class, FromRequest.class, Git.class})
|
||||||
|
|
|
||||||
|
|
@ -67,28 +67,38 @@ public class JsonSchemaMigration {
|
||||||
// TODO: make import flow migration reactive
|
// TODO: make import flow migration reactive
|
||||||
return Mono.just(migrateServerSchema(appJson))
|
return Mono.just(migrateServerSchema(appJson))
|
||||||
.flatMap(migratedApplicationJson -> {
|
.flatMap(migratedApplicationJson -> {
|
||||||
if (migratedApplicationJson.getServerSchemaVersion() == 9
|
// In Server version 9, there was a bug where the Embedded REST API datasource URL
|
||||||
&& Boolean.TRUE.equals(MigrationHelperMethods.doesRestApiRequireMigration(
|
// was not being persisted correctly. Once the bug was fixed,
|
||||||
migratedApplicationJson))) {
|
// any previously uncommitted changes started appearing as uncommitted modifications
|
||||||
return jsonSchemaMigrationHelper
|
// in the apps. To automatically commit these changes
|
||||||
.addDatasourceConfigurationToDefaultRestApiActions(
|
// (which were now appearing as uncommitted), a migration process was needed.
|
||||||
baseApplicationId, branchName, migratedApplicationJson)
|
// This migration fetches the datasource URL from the database
|
||||||
.map(applicationJsonWithMigration10 -> {
|
// and serializes it in Git if the URL exists.
|
||||||
applicationJsonWithMigration10.setServerSchemaVersion(10);
|
// If the URL is missing, it copies the empty datasource configuration
|
||||||
return applicationJsonWithMigration10;
|
// if the configuration is present in the database.
|
||||||
});
|
// Otherwise, it leaves the configuration unchanged.
|
||||||
|
// Due to an update in the migration logic after version 10 was shipped,
|
||||||
|
// the entire migration process was moved to version 11.
|
||||||
|
// This adjustment ensures that the same operation can be
|
||||||
|
// performed again for the changes introduced in version 10.
|
||||||
|
if (migratedApplicationJson.getServerSchemaVersion() == 9) {
|
||||||
|
migratedApplicationJson.setServerSchemaVersion(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (migratedApplicationJson.getServerSchemaVersion() == 10) {
|
||||||
|
if (Boolean.TRUE.equals(MigrationHelperMethods.doesRestApiRequireMigration(
|
||||||
|
migratedApplicationJson))) {
|
||||||
|
return jsonSchemaMigrationHelper
|
||||||
|
.addDatasourceConfigurationToDefaultRestApiActions(
|
||||||
|
baseApplicationId, branchName, migratedApplicationJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
migratedApplicationJson.setServerSchemaVersion(11);
|
||||||
}
|
}
|
||||||
|
|
||||||
migratedApplicationJson.setServerSchemaVersion(10);
|
|
||||||
return Mono.just(migratedApplicationJson);
|
return Mono.just(migratedApplicationJson);
|
||||||
})
|
})
|
||||||
.map(migratedAppJson -> {
|
.map(migratedAppJson -> {
|
||||||
if (applicationJson
|
|
||||||
.getServerSchemaVersion()
|
|
||||||
.equals(jsonSchemaVersions.getServerVersion())) {
|
|
||||||
return applicationJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion());
|
applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion());
|
||||||
return applicationJson;
|
return applicationJson;
|
||||||
});
|
});
|
||||||
|
|
@ -193,16 +203,14 @@ public class JsonSchemaMigration {
|
||||||
|
|
||||||
switch (applicationJson.getServerSchemaVersion()) {
|
switch (applicationJson.getServerSchemaVersion()) {
|
||||||
case 9:
|
case 9:
|
||||||
|
applicationJson.setServerSchemaVersion(10);
|
||||||
|
case 10:
|
||||||
// this if for cases where we have empty datasource configs
|
// this if for cases where we have empty datasource configs
|
||||||
MigrationHelperMethods.migrateApplicationJsonToVersionTen(applicationJson, Map.of());
|
MigrationHelperMethods.migrateApplicationJsonToVersionTen(applicationJson, Map.of());
|
||||||
applicationJson.setServerSchemaVersion(10);
|
applicationJson.setServerSchemaVersion(11);
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applicationJson.getServerSchemaVersion().equals(jsonSchemaVersions.getServerVersion())) {
|
|
||||||
return applicationJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion());
|
applicationJson.setServerSchemaVersion(jsonSchemaVersions.getServerVersion());
|
||||||
return applicationJson;
|
return applicationJson;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class JsonSchemaVersionsFallback {
|
public class JsonSchemaVersionsFallback {
|
||||||
private static final Integer serverVersion = 10;
|
private static final Integer serverVersion = 11;
|
||||||
public static final Integer clientVersion = 1;
|
public static final Integer clientVersion = 1;
|
||||||
|
|
||||||
public Integer getServerVersion() {
|
public Integer getServerVersion() {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.appsmith.external.constants.PluginConstants.PackageName.GRAPHQL_PLUGIN;
|
||||||
|
import static com.appsmith.external.constants.PluginConstants.PackageName.REST_API_PLUGIN;
|
||||||
import static com.appsmith.server.constants.ResourceModes.EDIT;
|
import static com.appsmith.server.constants.ResourceModes.EDIT;
|
||||||
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
||||||
import static org.springframework.data.mongodb.core.query.Criteria.where;
|
import static org.springframework.data.mongodb.core.query.Criteria.where;
|
||||||
|
|
@ -1235,13 +1237,34 @@ public class MigrationHelperMethods {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean conditionForDefaultRestDatasourceMigration(NewAction action) {
|
public static boolean conditionForDefaultRestDatasource(NewAction action) {
|
||||||
|
if (action.getUnpublishedAction() == null
|
||||||
|
|| action.getUnpublishedAction().getDatasource() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Datasource actionDatasource = action.getUnpublishedAction().getDatasource();
|
Datasource actionDatasource = action.getUnpublishedAction().getDatasource();
|
||||||
|
|
||||||
|
// probable check for the default rest datasource action is.
|
||||||
|
// it has no datasource id and action's plugin id is either rest-api or graphql plugin.
|
||||||
|
boolean probableCheckForDefaultRestDatasource = !org.springframework.util.StringUtils.hasText(
|
||||||
|
actionDatasource.getId())
|
||||||
|
&& (REST_API_PLUGIN.equals(action.getPluginId()) || GRAPHQL_PLUGIN.equals(action.getPluginId()));
|
||||||
|
|
||||||
// condition to check if the action is default rest datasource.
|
// condition to check if the action is default rest datasource.
|
||||||
// it has no datasource id and name is equal to DEFAULT_REST_DATASOURCE
|
// it has no datasource id and name is equal to DEFAULT_REST_DATASOURCE
|
||||||
boolean isActionDefaultRestDatasource = !org.springframework.util.StringUtils.hasText(actionDatasource.getId())
|
boolean certainCheckForDefaultRestDatasource =
|
||||||
&& PluginConstants.DEFAULT_REST_DATASOURCE.equals(actionDatasource.getName());
|
!org.springframework.util.StringUtils.hasText(actionDatasource.getId())
|
||||||
|
&& PluginConstants.DEFAULT_REST_DATASOURCE.equals(actionDatasource.getName());
|
||||||
|
|
||||||
|
// Two separate types of checks over here, it's either the obvious certain way to identify or
|
||||||
|
// the likely chance that the datasource is present.
|
||||||
|
return certainCheckForDefaultRestDatasource || probableCheckForDefaultRestDatasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean conditionForDefaultRestDatasourceMigration(NewAction action) {
|
||||||
|
boolean isActionDefaultRestDatasource = conditionForDefaultRestDatasource(action);
|
||||||
|
Datasource actionDatasource = action.getUnpublishedAction().getDatasource();
|
||||||
|
|
||||||
// condition to check if the action has missing url or has no config at all
|
// condition to check if the action has missing url or has no config at all
|
||||||
boolean isDatasourceConfigurationOrUrlMissing = actionDatasource.getDatasourceConfiguration() == null
|
boolean isDatasourceConfigurationOrUrlMissing = actionDatasource.getDatasourceConfiguration() == null
|
||||||
|
|
@ -1322,18 +1345,25 @@ public class MigrationHelperMethods {
|
||||||
|
|
||||||
if (defaultDatasourceActionMap.containsKey(action.getGitSyncId())) {
|
if (defaultDatasourceActionMap.containsKey(action.getGitSyncId())) {
|
||||||
NewAction actionFromMap = defaultDatasourceActionMap.get(action.getGitSyncId());
|
NewAction actionFromMap = defaultDatasourceActionMap.get(action.getGitSyncId());
|
||||||
|
// NPE check to avoid migration failures
|
||||||
|
if (actionFromMap.getUnpublishedAction() == null
|
||||||
|
|| actionFromMap.getUnpublishedAction().getDatasource() == null
|
||||||
|
|| actionFromMap.getUnpublishedAction().getDatasource().getDatasourceConfiguration() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the datasource config in the json action only if the datasource config from db is not null,
|
||||||
|
// else it'll start to show as uncommited changes.
|
||||||
DatasourceConfiguration datasourceConfigurationFromDBAction =
|
DatasourceConfiguration datasourceConfigurationFromDBAction =
|
||||||
actionFromMap.getUnpublishedAction().getDatasource().getDatasourceConfiguration();
|
actionFromMap.getUnpublishedAction().getDatasource().getDatasourceConfiguration();
|
||||||
|
|
||||||
if (datasourceConfigurationFromDBAction != null) {
|
// At this point it's established that datasource config of db action is not null.
|
||||||
datasourceConfiguration.setUrl(datasourceConfigurationFromDBAction.getUrl());
|
datasourceConfiguration.setUrl(datasourceConfigurationFromDBAction.getUrl());
|
||||||
}
|
actionDatasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||||
}
|
|
||||||
|
|
||||||
if (!org.springframework.util.StringUtils.hasText(datasourceConfiguration.getUrl())) {
|
} else {
|
||||||
datasourceConfiguration.setUrl("");
|
datasourceConfiguration.setUrl("");
|
||||||
|
actionDatasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
actionDatasource.setDatasourceConfiguration(datasourceConfiguration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.appsmith.server.migrations.utils;
|
package com.appsmith.server.migrations.utils;
|
||||||
|
|
||||||
import com.appsmith.external.constants.PluginConstants;
|
import com.appsmith.external.constants.PluginConstants;
|
||||||
|
import com.appsmith.external.models.Datasource;
|
||||||
|
import com.appsmith.external.models.PluginType;
|
||||||
import com.appsmith.server.applications.base.ApplicationService;
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.domains.Application;
|
import com.appsmith.server.domains.Application;
|
||||||
import com.appsmith.server.domains.NewAction;
|
import com.appsmith.server.domains.NewAction;
|
||||||
|
|
@ -51,14 +53,27 @@ public class JsonSchemaMigrationHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean reverseFlag = StringUtils.hasText(action.getUnpublishedAction()
|
Datasource actionDatasource =
|
||||||
.getDatasource()
|
action.getUnpublishedAction().getDatasource();
|
||||||
.getId())
|
|
||||||
|| !PluginConstants.DEFAULT_REST_DATASOURCE.equals(action.getUnpublishedAction()
|
|
||||||
.getDatasource()
|
|
||||||
.getName());
|
|
||||||
|
|
||||||
return !reverseFlag;
|
// lenient probable check for the default rest datasource action is.
|
||||||
|
// As we don't have any harm in the allowing API actions present in db.
|
||||||
|
// it has no datasource id and action's plugin type is API
|
||||||
|
boolean probableCheckForDefaultRestDatasource =
|
||||||
|
!org.springframework.util.StringUtils.hasText(actionDatasource.getId())
|
||||||
|
&& PluginType.API.equals(action.getPluginType());
|
||||||
|
|
||||||
|
// condition to check if the action is default rest datasource.
|
||||||
|
// it has no datasource id and name is equal to DEFAULT_REST_DATASOURCE
|
||||||
|
boolean certainCheckForDefaultRestDatasource =
|
||||||
|
!org.springframework.util.StringUtils.hasText(actionDatasource.getId())
|
||||||
|
&& PluginConstants.DEFAULT_REST_DATASOURCE.equals(
|
||||||
|
actionDatasource.getName());
|
||||||
|
|
||||||
|
// Two separate types of checks over here, it's either the obvious certain way to
|
||||||
|
// identify or
|
||||||
|
// the likely chance that the datasource is present.
|
||||||
|
return certainCheckForDefaultRestDatasource || probableCheckForDefaultRestDatasource;
|
||||||
})
|
})
|
||||||
.collectMap(NewAction::getGitSyncId);
|
.collectMap(NewAction::getGitSyncId);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services.ce;
|
||||||
|
|
||||||
import com.appsmith.external.models.ActionDTO;
|
import com.appsmith.external.models.ActionDTO;
|
||||||
import com.appsmith.external.models.Datasource;
|
import com.appsmith.external.models.Datasource;
|
||||||
|
|
@ -32,6 +32,14 @@ import com.appsmith.server.newpages.base.NewPageService;
|
||||||
import com.appsmith.server.plugins.base.PluginService;
|
import com.appsmith.server.plugins.base.PluginService;
|
||||||
import com.appsmith.server.repositories.ApplicationRepository;
|
import com.appsmith.server.repositories.ApplicationRepository;
|
||||||
import com.appsmith.server.repositories.NewPageRepository;
|
import com.appsmith.server.repositories.NewPageRepository;
|
||||||
|
import com.appsmith.server.services.ApplicationPageService;
|
||||||
|
import com.appsmith.server.services.ConsolidatedAPIService;
|
||||||
|
import com.appsmith.server.services.MockDataService;
|
||||||
|
import com.appsmith.server.services.ProductAlertService;
|
||||||
|
import com.appsmith.server.services.SessionUserService;
|
||||||
|
import com.appsmith.server.services.TenantService;
|
||||||
|
import com.appsmith.server.services.UserDataService;
|
||||||
|
import com.appsmith.server.services.UserService;
|
||||||
import com.appsmith.server.themes.base.ThemeService;
|
import com.appsmith.server.themes.base.ThemeService;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
Loading…
Reference in New Issue
Block a user