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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package com.appsmith.server.services.ce; package com.appsmith.server.services.ce;
import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Application;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.ApplicationTemplate; import com.appsmith.server.dtos.ApplicationTemplate;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
@ -9,11 +10,18 @@ import reactor.core.publisher.Mono;
import java.util.List; import java.util.List;
public interface ApplicationTemplateServiceCE { public interface ApplicationTemplateServiceCE {
Mono<List<ApplicationTemplate>> getActiveTemplates(List<String> templateIds); Mono<List<ApplicationTemplate>> getActiveTemplates(List<String> templateIds);
Flux<ApplicationTemplate> getSimilarTemplates(String templateId, MultiValueMap<String, String> params); Flux<ApplicationTemplate> getSimilarTemplates(String templateId, MultiValueMap<String, String> params);
Mono<List<ApplicationTemplate>> getRecentlyUsedTemplates(); Mono<List<ApplicationTemplate>> getRecentlyUsedTemplates();
Mono<ApplicationTemplate> getTemplateDetails(String templateId); 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<Application> mergeTemplateWithApplication(String templateId, String applicationId, String workspaceId, String branchName, List<String> pagesToImport);
Mono<ApplicationTemplate> getFilters(); 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.configurations.CloudServicesConfig;
import com.appsmith.server.domains.Application; import com.appsmith.server.domains.Application;
import com.appsmith.server.domains.UserData; import com.appsmith.server.domains.UserData;
import com.appsmith.server.dtos.ApplicationImportDTO;
import com.appsmith.server.dtos.ApplicationJson; import com.appsmith.server.dtos.ApplicationJson;
import com.appsmith.server.dtos.ApplicationTemplate; import com.appsmith.server.dtos.ApplicationTemplate;
import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithError;
@ -181,18 +182,20 @@ public class ApplicationTemplateServiceCEImpl implements ApplicationTemplateServ
} }
@Override @Override
public Mono<Application> importApplicationFromTemplate(String templateId, String workspaceId) { public Mono<ApplicationImportDTO> importApplicationFromTemplate(String templateId, String workspaceId) {
return getApplicationJsonFromTemplate(templateId).flatMap(applicationJson -> return getApplicationJsonFromTemplate(templateId)
importExportApplicationService.importApplicationInWorkspace(workspaceId, applicationJson) .flatMap(applicationJson -> importExportApplicationService.importApplicationInWorkspace(workspaceId, applicationJson))
).flatMap(application -> { .flatMap(application -> importExportApplicationService.getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application))
ApplicationTemplate applicationTemplate = new ApplicationTemplate(); .flatMap(applicationImportDTO -> {
applicationTemplate.setId(templateId); Application application = applicationImportDTO.getApplication();
Map<String, Object> extraProperties = new HashMap<>(); ApplicationTemplate applicationTemplate = new ApplicationTemplate();
extraProperties.put("templateAppName", application.getName()); applicationTemplate.setId(templateId);
return userDataService.addTemplateIdToLastUsedList(templateId).then( Map<String, Object> extraProperties = new HashMap<>();
extraProperties.put("templateAppName", application.getName());
return userDataService.addTemplateIdToLastUsedList(templateId).then(
analyticsService.sendObjectEvent(AnalyticsEvents.FORK, applicationTemplate, extraProperties) analyticsService.sendObjectEvent(AnalyticsEvents.FORK, applicationTemplate, extraProperties)
).thenReturn(application); ).thenReturn(applicationImportDTO);
}); });
} }
@Override @Override

View File

@ -1999,19 +1999,7 @@ public class GitServiceCEImpl implements GitServiceCE {
}); });
}) })
// Add un-configured datasource to the list to response // Add un-configured datasource to the list to response
.flatMap(application -> importExportApplicationService.findDatasourceByApplicationId(application.getId(), application.getWorkspaceId()) .flatMap(application -> importExportApplicationService.getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application))
.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;
}))
// Add analytics event // Add analytics event
.flatMap(applicationImportDTO -> { .flatMap(applicationImportDTO -> {
Application application = applicationImportDTO.getApplication(); Application application = applicationImportDTO.getApplication();

View File

@ -61,4 +61,6 @@ public interface ImportExportApplicationServiceCE {
Mono<List<Datasource>> findDatasourceByApplicationId(String applicationId, String orgId); 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 // Add un-configured datasource to the list to response
.flatMap(application -> findDatasourceByApplicationId(application.getId(), workspaceId) .flatMap(application -> getApplicationImportDTO(application.getId(), application.getWorkspaceId(), application));
.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;
}));
return Mono.create(sink -> importedApplicationMono return Mono.create(sink -> importedApplicationMono
.subscribe(sink::success, sink::error, null, sink.currentContext()) .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 * @param applicationId default ID of the application where this ApplicationJSON is going to get merged with