feat: Added unconfigured datasources to the template API response (#15606)

Co-authored-by: Akash N <akash@codemonk.in>
This commit is contained in:
Anagh Hegde 2022-08-04 09:50:54 +05:30 committed by GitHub
parent 3cb57b531d
commit 82a9d720ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 48 deletions

View File

@ -3,6 +3,7 @@ import Api from "api/Api";
import { ApiResponse } from "./ApiResponses";
import { WidgetType } from "constants/WidgetConstants";
import { ApplicationResponsePayload } from "./ApplicationApi";
import { Datasource } from "entities/Datasource";
export interface Template {
id: string;
@ -23,7 +24,11 @@ export type FilterKeys = "widgets" | "datasources";
export type FetchTemplateResponse = ApiResponse<Template>;
export type ImportTemplateResponse = ApiResponse<ApplicationResponsePayload>;
export type ImportTemplateResponse = ApiResponse<{
isPartialImport: boolean;
unConfiguredDatasourceList: Datasource[];
application: ApplicationResponsePayload;
}>;
class TemplatesAPI extends Api {
static baseUrl = "v1";

View File

@ -41,6 +41,7 @@ import {
VIEW_ALL_TEMPLATES,
} from "@appsmith/constants/messages";
import AnalyticsUtil from "utils/AnalyticsUtil";
import ReconnectDatasourceModal from "pages/Editor/gitSync/ReconnectDatasourceModal";
const breakpointColumnsObject = {
default: 4,
@ -289,6 +290,7 @@ function TemplateView() {
<TemplateNotFound />
) : (
<Wrapper ref={containerRef}>
<ReconnectDatasourceModal />
<TemplateViewWrapper>
<HeaderWrapper>
<div className="left">

View File

@ -31,6 +31,7 @@ import { getAllApplications } from "actions/applicationActions";
import { getTypographyByKey } from "constants/DefaultTheme";
import { Colors } from "constants/Colors";
import { createMessage, SEARCH_TEMPLATES } from "@appsmith/constants/messages";
import ReconnectDatasourceModal from "pages/Editor/gitSync/ReconnectDatasourceModal";
const SentryRoute = Sentry.withSentryRouting(Route);
const PageWrapper = styled.div`
@ -162,6 +163,7 @@ function Templates() {
return (
<PageWrapper>
<ReconnectDatasourceModal />
<Filters />
<TemplateListWrapper>
{isLoading ? (

View File

@ -18,6 +18,7 @@ import {
} from "utils/storage";
import { validateResponse } from "./ErrorSagas";
import { builderURL } from "RouteBuilder";
import { showReconnectDatasourceModal } from "actions/applicationActions";
function* getAllTemplatesSaga() {
try {
@ -53,17 +54,31 @@ function* importTemplateToWorkspaceSaga(
const isValid: boolean = yield validateResponse(response);
if (isValid) {
const application: ApplicationPayload = {
...response.data,
defaultPageId: getDefaultPageId(response.data.pages) as string,
...response.data.application,
defaultPageId: getDefaultPageId(
response.data.application.pages,
) as string,
};
yield put({
type: ReduxActionTypes.IMPORT_TEMPLATE_TO_WORKSPACE_SUCCESS,
payload: response.data,
payload: response.data.application,
});
const pageURL = builderURL({
pageId: application.defaultPageId,
});
history.push(pageURL);
if (response.data.isPartialImport) {
yield put(
showReconnectDatasourceModal({
application: response.data.application,
unConfiguredDatasourceList:
response.data.unConfiguredDatasourceList,
workspaceId: action.payload.workspaceId,
}),
);
} else {
const pageURL = builderURL({
pageId: application.defaultPageId,
});
history.push(pageURL);
}
}
} catch (error) {
yield put({

View File

@ -2,6 +2,7 @@ package com.appsmith.server.controllers.ce;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Application;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.ApplicationTemplate;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.services.ApplicationTemplateService;
@ -52,8 +53,8 @@ public class ApplicationTemplateControllerCE {
}
@PostMapping("{templateId}/import/{workspaceId}")
public Mono<ResponseDTO<Application>> importApplicationFromTemplate(@PathVariable String templateId,
@PathVariable String workspaceId) {
public Mono<ResponseDTO<ApplicationImportDTO>> importApplicationFromTemplate(@PathVariable String templateId,
@PathVariable String workspaceId) {
return applicationTemplateService.importApplicationFromTemplate(templateId, workspaceId)
.map(importedApp -> new ResponseDTO<>(HttpStatus.OK.value(), importedApp, null));
}

View File

@ -1,6 +1,7 @@
package com.appsmith.server.services.ce;
import com.appsmith.server.domains.Application;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.ApplicationTemplate;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux;
@ -9,11 +10,18 @@ import reactor.core.publisher.Mono;
import java.util.List;
public interface ApplicationTemplateServiceCE {
Mono<List<ApplicationTemplate>> getActiveTemplates(List<String> templateIds);
Flux<ApplicationTemplate> getSimilarTemplates(String templateId, MultiValueMap<String, String> params);
Mono<List<ApplicationTemplate>> getRecentlyUsedTemplates();
Mono<ApplicationTemplate> getTemplateDetails(String templateId);
Mono<Application> importApplicationFromTemplate(String templateId, String workspaceId);
Mono<ApplicationImportDTO> importApplicationFromTemplate(String templateId, String workspaceId);
Mono<Application> mergeTemplateWithApplication(String templateId, String applicationId, String workspaceId, String branchName, List<String> pagesToImport);
Mono<ApplicationTemplate> getFilters();
}

View File

@ -5,6 +5,7 @@ import com.appsmith.external.converters.GsonISOStringToInstantConverter;
import com.appsmith.server.configurations.CloudServicesConfig;
import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.UserData;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.ApplicationJson;
import com.appsmith.server.dtos.ApplicationTemplate;
import com.appsmith.server.exceptions.AppsmithError;
@ -181,18 +182,20 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ
}
@Override
public Mono<Application> importApplicationFromTemplate(String templateId, String workspaceId) {
return getApplicationJsonFromTemplate(templateId).flatMap(applicationJson ->
importExportApplicationService.importApplicationInWorkspace(workspaceId, applicationJson)
).flatMap(application -> {
ApplicationTemplate applicationTemplate = new ApplicationTemplate();
applicationTemplate.setId(templateId);
Map<String, Object> extraProperties = new HashMap<>();
extraProperties.put("templateAppName", application.getName());
return userDataService.addTemplateIdToLastUsedList(templateId).then(
public Mono<ApplicationImportDTO> importApplicationFromTemplate(String templateId, String workspaceId) {
return getApplicationJsonFromTemplate(templateId)
.flatMap(applicationJson -> importExportApplicationService.importApplicationInWorkspace(workspaceId, applicationJson))
.flatMap(application -> importExportApplicationService.getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application))
.flatMap(applicationImportDTO -> {
Application application = applicationImportDTO.getApplication();
ApplicationTemplate applicationTemplate = new ApplicationTemplate();
applicationTemplate.setId(templateId);
Map<String, Object> extraProperties = new HashMap<>();
extraProperties.put("templateAppName", application.getName());
return userDataService.addTemplateIdToLastUsedList(templateId).then(
analyticsService.sendObjectEvent(AnalyticsEvents.FORK, applicationTemplate, extraProperties)
).thenReturn(application);
});
).thenReturn(applicationImportDTO);
});
}
@Override

View File

@ -1999,19 +1999,7 @@ public class GitServiceCEImpl implements GitServiceCE {
});
})
// Add un-configured datasource to the list to response
.flatMap(application -> importExportApplicationService.findDatasourceByApplicationId(application.getId(), application.getWorkspaceId())
.map(datasources -> {
ApplicationImportDTO applicationImportDTO = new ApplicationImportDTO();
applicationImportDTO.setApplication(application);
long unConfiguredDatasource = datasources.stream().filter(datasource -> Boolean.FALSE.equals(datasource.getIsConfigured())).count();
if (unConfiguredDatasource != 0) {
applicationImportDTO.setIsPartialImport(true);
applicationImportDTO.setUnConfiguredDatasourceList(datasources);
} else {
applicationImportDTO.setIsPartialImport(false);
}
return applicationImportDTO;
}))
.flatMap(application -> importExportApplicationService.getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application))
// Add analytics event
.flatMap(applicationImportDTO -> {
Application application = applicationImportDTO.getApplication();

View File

@ -61,4 +61,6 @@ public interface ImportExportApplicationServiceCE {
Mono<List<Datasource>> findDatasourceByApplicationId(String applicationId, String orgId);
Mono<ApplicationImportDTO> getApplicationImportDTO(String applicationId, String workspaceId, Application application);
}

View File

@ -577,19 +577,7 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica
});
})
// Add un-configured datasource to the list to response
.flatMap(application -> findDatasourceByApplicationId(application.getId(), workspaceId)
.map(datasources -> {
ApplicationImportDTO applicationImportDTO = new ApplicationImportDTO();
applicationImportDTO.setApplication(application);
Long unConfiguredDatasource = datasources.stream().filter(datasource -> Boolean.FALSE.equals(datasource.getIsConfigured())).count();
if (unConfiguredDatasource != 0) {
applicationImportDTO.setIsPartialImport(true);
applicationImportDTO.setUnConfiguredDatasourceList(datasources);
} else {
applicationImportDTO.setIsPartialImport(false);
}
return applicationImportDTO;
}));
.flatMap(application -> getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application));
return Mono.create(sink -> importedApplicationMono
.subscribe(sink::success, sink::error, null, sink.currentContext())
@ -1990,6 +1978,23 @@ public class ImportExportApplicationServiceCEImpl implements ImportExportApplica
});
}
@Override
public Mono<ApplicationImportDTO> getApplicationImportDTO(String applicationId, String workspaceId, Application application) {
return findDatasourceByApplicationId(applicationId, workspaceId)
.map(datasources -> {
ApplicationImportDTO applicationImportDTO = new ApplicationImportDTO();
applicationImportDTO.setApplication(application);
Boolean isUnConfiguredDatasource = datasources.stream().anyMatch(datasource -> Boolean.FALSE.equals(datasource.getIsConfigured()));
if (Boolean.TRUE.equals(isUnConfiguredDatasource)) {
applicationImportDTO.setIsPartialImport(true);
applicationImportDTO.setUnConfiguredDatasourceList(datasources);
} else {
applicationImportDTO.setIsPartialImport(false);
}
return applicationImportDTO;
});
}
/**
*
* @param applicationId default ID of the application where this ApplicationJSON is going to get merged with