feat: add last edit information to application (#6948)
Adds the last edit time and editor username to the application when there is a change in the application.
This commit is contained in:
parent
7a0ec72304
commit
c4a7c1fb01
|
|
@ -70,6 +70,18 @@ public class Application extends BaseDomain {
|
|||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
Instant lastDeployedAt; // when this application was last deployed
|
||||
|
||||
/**
|
||||
* This method has been added because the updatedAt property in base domain has @JsonIgnore annotation
|
||||
* @return updated time as a string
|
||||
*/
|
||||
@JsonProperty(value = "modifiedAt", access = JsonProperty.Access.READ_ONLY)
|
||||
public String getLastUpdateTime() {
|
||||
if(updatedAt != null) {
|
||||
return ISO_FORMATTER.format(updatedAt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLastDeployedAt() {
|
||||
if(lastDeployedAt != null) {
|
||||
return ISO_FORMATTER.format(lastDeployedAt);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -122,6 +123,8 @@ public abstract class BaseAppsmithRepositoryImpl<T extends BaseDomain> {
|
|||
|
||||
// Set policies to null in the update object
|
||||
resource.setPolicies(null);
|
||||
resource.setUpdatedAt(Instant.now());
|
||||
resource.setModifiedBy(user.getUsername());
|
||||
|
||||
DBObject update = getDbObject(resource);
|
||||
Update updateObj = new Update();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.appsmith.server.repositories;
|
||||
|
||||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.Application;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.domains.QApplication;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
|||
final PageDTO savedPage = tuple.getT1();
|
||||
final Application application = tuple.getT2();
|
||||
return addPageToApplication(application, savedPage, false)
|
||||
.then(applicationService.saveLastEditInformation(application.getId()))
|
||||
.thenReturn(savedPage);
|
||||
});
|
||||
}
|
||||
|
|
@ -309,7 +310,10 @@ public class ApplicationPageServiceImpl implements ApplicationPageService {
|
|||
|
||||
return newPageService.findById(pageId, MANAGE_PAGES)
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.ACTION_IS_NOT_AUTHORIZED, "Clone Page")))
|
||||
.flatMap(page -> clonePageGivenApplicationId(pageId, page.getApplicationId(), " Copy"));
|
||||
.flatMap(page ->
|
||||
applicationService.saveLastEditInformation(page.getApplicationId())
|
||||
.then(clonePageGivenApplicationId(pageId, page.getApplicationId(), " Copy"))
|
||||
);
|
||||
}
|
||||
|
||||
private Mono<PageDTO> clonePageGivenApplicationId(String pageId, String applicationId,
|
||||
|
|
|
|||
|
|
@ -31,4 +31,6 @@ public interface ApplicationService extends CrudService<Application, String> {
|
|||
Flux<Application> findAllApplicationsByOrganizationId(String organizationId);
|
||||
|
||||
Mono<Application> getApplicationInViewMode(String applicationId);
|
||||
|
||||
Mono<Application> saveLastEditInformation(String applicationId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import java.util.Set;
|
|||
|
||||
import static com.appsmith.server.acl.AclPermission.EXECUTE_DATASOURCES;
|
||||
import static com.appsmith.server.acl.AclPermission.MAKE_PUBLIC_APPLICATIONS;
|
||||
import static com.appsmith.server.acl.AclPermission.MANAGE_APPLICATIONS;
|
||||
import static com.appsmith.server.acl.AclPermission.READ_APPLICATIONS;
|
||||
|
||||
|
||||
|
|
@ -301,4 +302,18 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the updatedAt and modifiedBy fields of the Application
|
||||
* @param applicationId Application ID
|
||||
* @return Application Mono of updated Application
|
||||
*/
|
||||
@Override
|
||||
public Mono<Application> saveLastEditInformation(String applicationId) {
|
||||
Application application = new Application();
|
||||
/*
|
||||
We're not setting updatedAt and modifiedBy fields to the application DTO because these fields will be set
|
||||
by the updateById method of the BaseAppsmithRepositoryImpl
|
||||
*/
|
||||
return repository.updateById(applicationId, application, MANAGE_APPLICATIONS); // it'll do a set operation
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.appsmith.server.helpers.WidgetSpecificUtils;
|
|||
import com.appsmith.server.solutions.PageLoadActionsUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.minidev.json.JSONObject;
|
||||
import net.minidev.json.parser.JSONParser;
|
||||
|
|
@ -56,6 +57,7 @@ import static java.util.stream.Collectors.toSet;
|
|||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class LayoutActionServiceImpl implements LayoutActionService {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
|
@ -64,6 +66,7 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
private final NewActionService newActionService;
|
||||
private final PageLoadActionsUtil pageLoadActionsUtil;
|
||||
private final SessionUserService sessionUserService;
|
||||
private final ApplicationService applicationService;
|
||||
private JSONParser jsonParser = new JSONParser(JSONParser.MODE_PERMISSIVE);
|
||||
|
||||
|
||||
|
|
@ -75,20 +78,6 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
private final String preWord = "\\b(";
|
||||
private final String postWord = ")\\b";
|
||||
|
||||
public LayoutActionServiceImpl(ObjectMapper objectMapper,
|
||||
AnalyticsService analyticsService,
|
||||
NewPageService newPageService,
|
||||
NewActionService newActionService,
|
||||
PageLoadActionsUtil pageLoadActionsUtil,
|
||||
SessionUserService sessionUserService) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.analyticsService = analyticsService;
|
||||
this.newPageService = newPageService;
|
||||
this.newActionService = newActionService;
|
||||
this.pageLoadActionsUtil = pageLoadActionsUtil;
|
||||
this.sessionUserService = sessionUserService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ActionDTO> moveAction(ActionMoveDTO actionMoveDTO) {
|
||||
ActionDTO action = actionMoveDTO.getAction();
|
||||
|
|
@ -676,7 +665,8 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
}
|
||||
}
|
||||
page.setLayouts(layoutList);
|
||||
return newPageService.saveUnpublishedPage(page);
|
||||
return applicationService.saveLastEditInformation(page.getApplicationId())
|
||||
.then(newPageService.saveUnpublishedPage(page));
|
||||
})
|
||||
.flatMap(page -> {
|
||||
List<Layout> layoutList = page.getLayouts();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.appsmith.server.acl.AclPermission;
|
|||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.Application;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.domains.Collection;
|
||||
import com.appsmith.server.domains.Layout;
|
||||
import com.appsmith.server.domains.NewPage;
|
||||
import com.appsmith.server.dtos.ApplicationPagesDTO;
|
||||
|
|
@ -381,7 +380,8 @@ public class NewPageServiceImpl extends BaseService<NewPageRepository, NewPage,
|
|||
copyNewFieldValuesIntoOldObject(page, dbPage.getUnpublishedPage());
|
||||
return this.update(id, dbPage);
|
||||
})
|
||||
.flatMap(savedPage -> getPageByViewMode(savedPage, false));
|
||||
.flatMap(savedPage -> applicationService.saveLastEditInformation(savedPage.getApplicationId())
|
||||
.then(getPageByViewMode(savedPage, false)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public class ImportExportApplicationService {
|
|||
final String organizationId = application.getOrganizationId();
|
||||
application.setOrganizationId(null);
|
||||
application.setPages(null);
|
||||
application.setModifiedBy(null);
|
||||
examplesOrganizationCloner.makePristine(application);
|
||||
applicationJson.setExportedApplication(application);
|
||||
return newPageRepository.findByApplicationId(applicationId, AclPermission.MANAGE_PAGES)
|
||||
|
|
|
|||
|
|
@ -1238,4 +1238,22 @@ public class ApplicationServiceTest {
|
|||
.verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
@WithUserDetails("api_user")
|
||||
@Test
|
||||
public void saveLastEditInformation_WhenUserHasPermission_Updated() {
|
||||
Application testApplication = new Application();
|
||||
testApplication.setName("SaveLastEditInformation TestApp");
|
||||
testApplication.setModifiedBy("test-user");
|
||||
|
||||
Mono<Application> updatedApplication = applicationPageService.createApplication(testApplication, orgId)
|
||||
.flatMap(application ->
|
||||
applicationService.saveLastEditInformation(application.getId())
|
||||
);
|
||||
StepVerifier.create(updatedApplication).assertNext(application -> {
|
||||
assertThat(application.getLastUpdateTime()).isNotNull();
|
||||
assertThat(application.getPolicies()).isNotNull().isNotEmpty();
|
||||
assertThat(application.getModifiedBy()).isEqualTo("api_user");
|
||||
}).verifyComplete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user