chore: complimentary pr for CD migration changes (#35876)
## Description > CE changes for CD migration on EE pr: https://github.com/appsmithorg/appsmith-ee/pull/4927 ## Automation /ok-to-test tags="@tag.Git" ### 🔍 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/10599263403> > Commit: ef94bff3b0d12db1a5003a78ce8ddfeabbb3c87d > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10599263403&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Wed, 28 Aug 2024 15:23:46 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new field for tracking the continuous deployment migration version in application metadata. - Enhanced Git artifact management with additional metadata for improved deployment processes. - **Bug Fixes** - Resolved issues related to application versioning and deployment tracking. - **Refactor** - Substantial restructuring of the Application class for improved maintainability and extensibility. - Simplified structure of GitArtifactMetadata, enhancing functionality and clarity. - **Tests** - Expanded equality tests for new entities related to the Application class, ensuring proper validation of equality logic. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
db3f35691d
commit
a36b45de60
|
|
@ -1,36 +1,16 @@
|
|||
package com.appsmith.server.domains;
|
||||
|
||||
import com.appsmith.external.models.BaseDomain;
|
||||
import com.appsmith.external.views.Git;
|
||||
import com.appsmith.external.views.Views;
|
||||
import com.appsmith.server.constants.ArtifactType;
|
||||
import com.appsmith.server.dtos.CustomJSLibContextDTO;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import com.appsmith.server.domains.ce.ApplicationCE;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.appsmith.external.helpers.StringUtils.dotted;
|
||||
import static com.appsmith.server.constants.ResourceModes.EDIT;
|
||||
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
||||
import static com.appsmith.server.helpers.DateUtils.ISO_FORMATTER;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
|
@ -38,349 +18,20 @@ import static com.appsmith.server.helpers.DateUtils.ISO_FORMATTER;
|
|||
@NoArgsConstructor
|
||||
@Document
|
||||
@FieldNameConstants
|
||||
public class Application extends BaseDomain implements Artifact {
|
||||
|
||||
@NotNull @JsonView(Views.Public.class)
|
||||
String name;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
String workspaceId;
|
||||
|
||||
// TODO: remove default values from application
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@Deprecated(forRemoval = true)
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isPublic = false;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
List<ApplicationPage> pages;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
List<ApplicationPage> publishedPages;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Transient
|
||||
Boolean viewMode = false;
|
||||
|
||||
@Transient
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
boolean appIsExample = false;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
long unreadCommentThreads;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String clonedFromApplicationId;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
ApplicationDetail unpublishedApplicationDetail;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
ApplicationDetail publishedApplicationDetail;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
String color;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
String icon;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
private String slug;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
AppLayout unpublishedAppLayout;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
AppLayout publishedAppLayout;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Set<CustomJSLibContextDTO> unpublishedCustomJSLibs;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Set<CustomJSLibContextDTO> publishedCustomJSLibs;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
GitArtifactMetadata gitApplicationMetadata;
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView(Views.Public.class)
|
||||
Instant lastDeployedAt; // when this application was last deployed
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Integer evaluationVersion;
|
||||
|
||||
/**
|
||||
* applicationVersion will be used when we've a breaking change in application, and it's not possible to write a
|
||||
* migration. User need to update the application manually.
|
||||
* In such cases, we can use this field to determine whether we need to notify user about that breaking change
|
||||
* so that they can update their application.
|
||||
* Once updated, we should set applicationVersion to latest version as well.
|
||||
*/
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Integer applicationVersion;
|
||||
|
||||
/**
|
||||
* Changing name, change in pages, widgets and datasources will set lastEditedAt.
|
||||
* Other activities e.g. changing policy will not change this property.
|
||||
* We're adding JsonIgnore here because it'll be exposed as modifiedAt to keep it backward compatible
|
||||
*/
|
||||
@JsonView(Views.Internal.class)
|
||||
Instant lastEditedAt;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
EmbedSetting embedSetting;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Boolean collapseInvisibleWidgets;
|
||||
|
||||
/**
|
||||
* Earlier this was returning value of the updatedAt property in the base domain.
|
||||
* As this property is modified by the framework when there is any change in domain,
|
||||
* a new property lastEditedAt has been added to track the edit actions from users.
|
||||
* This method exposes that property.
|
||||
*
|
||||
* @return updated time as a string
|
||||
*/
|
||||
@JsonProperty(value = "modifiedAt", access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView(Views.Public.class)
|
||||
public String getLastUpdateTime() {
|
||||
if (lastEditedAt != null) {
|
||||
return ISO_FORMATTER.format(lastEditedAt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
public String getLastDeployedAt() {
|
||||
if (lastDeployedAt != null) {
|
||||
return ISO_FORMATTER.format(lastDeployedAt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean forkingEnabled;
|
||||
|
||||
// Field to convey if the application is updated by the user
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isManualUpdate;
|
||||
|
||||
// Field to convey if the application is modified from the DB migration
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isAutoUpdate;
|
||||
|
||||
// To convey current schema version for client and server. This will be used to check if we run the migration
|
||||
// between 2 commits if the application is connected to git
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
Integer clientSchemaVersion;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
Integer serverSchemaVersion;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String publishedModeThemeId;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String editModeThemeId;
|
||||
|
||||
// TODO Temporary provision for exporting the application with datasource configuration for the sample/template apps
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean exportWithConfiguration;
|
||||
|
||||
// forkWithConfiguration represents whether credentials are shared or not while forking an app
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean forkWithConfiguration;
|
||||
|
||||
// isCommunityTemplate represents whether this application has been published as a community template
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isCommunityTemplate;
|
||||
|
||||
/* Template title of the template from which this app was forked, if any */
|
||||
@JsonView(Views.Public.class)
|
||||
String forkedFromTemplateTitle;
|
||||
public class Application extends ApplicationCE implements Artifact {
|
||||
|
||||
// This constructor is used during clone application. It only deeply copies selected fields. The rest are either
|
||||
// initialized newly or is left up to the calling function to set.
|
||||
public Application(Application application) {
|
||||
super();
|
||||
this.workspaceId = application.getWorkspaceId();
|
||||
this.pages = new ArrayList<>();
|
||||
this.publishedPages = new ArrayList<>();
|
||||
this.clonedFromApplicationId = application.getId();
|
||||
this.color = application.getColor();
|
||||
this.icon = application.getIcon();
|
||||
this.unpublishedAppLayout = application.getUnpublishedAppLayout() == null
|
||||
? null
|
||||
: new AppLayout(application.getUnpublishedAppLayout().type);
|
||||
this.publishedAppLayout = application.getPublishedAppLayout() == null
|
||||
? null
|
||||
: new AppLayout(application.getPublishedAppLayout().type);
|
||||
this.setUnpublishedApplicationDetail(new ApplicationDetail());
|
||||
this.setPublishedApplicationDetail(new ApplicationDetail());
|
||||
if (application.getUnpublishedApplicationDetail() == null) {
|
||||
application.setUnpublishedApplicationDetail(new ApplicationDetail());
|
||||
}
|
||||
if (application.getPublishedApplicationDetail() == null) {
|
||||
application.setPublishedApplicationDetail(new ApplicationDetail());
|
||||
}
|
||||
AppPositioning unpublishedAppPositioning =
|
||||
application.getUnpublishedApplicationDetail().getAppPositioning() == null
|
||||
? null
|
||||
: new AppPositioning(
|
||||
application.getUnpublishedApplicationDetail().getAppPositioning().type);
|
||||
this.getUnpublishedApplicationDetail().setAppPositioning(unpublishedAppPositioning);
|
||||
AppPositioning publishedAppPositioning =
|
||||
application.getPublishedApplicationDetail().getAppPositioning() == null
|
||||
? null
|
||||
: new AppPositioning(
|
||||
application.getPublishedApplicationDetail().getAppPositioning().type);
|
||||
this.getPublishedApplicationDetail().setAppPositioning(publishedAppPositioning);
|
||||
this.getUnpublishedApplicationDetail()
|
||||
.setNavigationSetting(
|
||||
application.getUnpublishedApplicationDetail().getNavigationSetting() == null
|
||||
? null
|
||||
: new NavigationSetting());
|
||||
this.getPublishedApplicationDetail()
|
||||
.setNavigationSetting(
|
||||
application.getPublishedApplicationDetail().getNavigationSetting() == null
|
||||
? null
|
||||
: new NavigationSetting());
|
||||
this.getUnpublishedApplicationDetail()
|
||||
.setThemeSetting(
|
||||
application.getUnpublishedApplicationDetail().getThemeSetting() == null
|
||||
? null
|
||||
: new ThemeSetting());
|
||||
this.getPublishedApplicationDetail()
|
||||
.setThemeSetting(
|
||||
application.getPublishedApplicationDetail().getThemeSetting() == null
|
||||
? null
|
||||
: new ThemeSetting());
|
||||
this.unpublishedCustomJSLibs = application.getUnpublishedCustomJSLibs();
|
||||
this.collapseInvisibleWidgets = application.getCollapseInvisibleWidgets();
|
||||
}
|
||||
|
||||
public void exportApplicationPages(final Map<String, String> pageIdToNameMap) {
|
||||
for (ApplicationPage applicationPage : this.getPages()) {
|
||||
applicationPage.setId(pageIdToNameMap.get(applicationPage.getId() + EDIT));
|
||||
applicationPage.setDefaultPageId(null);
|
||||
}
|
||||
for (ApplicationPage applicationPage : this.getPublishedPages()) {
|
||||
applicationPage.setId(pageIdToNameMap.get(applicationPage.getId() + VIEW));
|
||||
applicationPage.setDefaultPageId(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseId() {
|
||||
if (this.getGitArtifactMetadata() != null
|
||||
&& StringUtils.hasLength(this.getGitArtifactMetadata().getDefaultArtifactId())) {
|
||||
return this.getGitArtifactMetadata().getDefaultArtifactId();
|
||||
}
|
||||
return Artifact.super.getBaseId();
|
||||
}
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Override
|
||||
public GitArtifactMetadata getGitArtifactMetadata() {
|
||||
return this.gitApplicationMetadata;
|
||||
}
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Override
|
||||
public void setGitArtifactMetadata(GitArtifactMetadata gitArtifactMetadata) {
|
||||
this.gitApplicationMetadata = gitArtifactMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnpublishedThemeId() {
|
||||
return this.getEditModeThemeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnpublishedThemeId(String themeId) {
|
||||
this.setEditModeThemeId(themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublishedThemeId() {
|
||||
return this.getPublishedModeThemeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublishedThemeId(String themeId) {
|
||||
this.setPublishedModeThemeId(themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sanitiseToExportDBObject() {
|
||||
this.setWorkspaceId(null);
|
||||
this.setModifiedBy(null);
|
||||
this.setCreatedBy(null);
|
||||
this.setLastDeployedAt(null);
|
||||
this.setLastEditedAt(null);
|
||||
this.setGitApplicationMetadata(null);
|
||||
this.setEditModeThemeId(null);
|
||||
this.setPublishedModeThemeId(null);
|
||||
this.setClientSchemaVersion(null);
|
||||
this.setServerSchemaVersion(null);
|
||||
this.setIsManualUpdate(false);
|
||||
this.setPublishedCustomJSLibs(new HashSet<>());
|
||||
this.setExportWithConfiguration(null);
|
||||
this.setForkWithConfiguration(null);
|
||||
this.setForkingEnabled(null);
|
||||
super.sanitiseToExportDBObject();
|
||||
}
|
||||
|
||||
public List<ApplicationPage> getPages() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedPages : pages;
|
||||
}
|
||||
|
||||
public AppLayout getAppLayout() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedAppLayout : unpublishedAppLayout;
|
||||
}
|
||||
|
||||
public void setAppLayout(AppLayout appLayout) {
|
||||
if (Boolean.TRUE.equals(viewMode)) {
|
||||
publishedAppLayout = appLayout;
|
||||
} else {
|
||||
unpublishedAppLayout = appLayout;
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationDetail getApplicationDetail() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedApplicationDetail : unpublishedApplicationDetail;
|
||||
}
|
||||
|
||||
public void setApplicationDetail(ApplicationDetail applicationDetail) {
|
||||
if (Boolean.TRUE.equals(viewMode)) {
|
||||
publishedApplicationDetail = applicationDetail;
|
||||
} else {
|
||||
unpublishedApplicationDetail = applicationDetail;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonView({Views.Internal.class})
|
||||
public ArtifactType getArtifactType() {
|
||||
return ArtifactType.APPLICATION;
|
||||
super(application);
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class AppLayout implements Serializable {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Type type;
|
||||
|
||||
public enum Type {
|
||||
DESKTOP,
|
||||
TABLET_LARGE,
|
||||
TABLET,
|
||||
MOBILE,
|
||||
FLUID,
|
||||
public static class AppLayout extends AppLayoutCE implements Serializable {
|
||||
public AppLayout(AppLayout.Type type) {
|
||||
super(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -388,136 +39,40 @@ public class Application extends BaseDomain implements Artifact {
|
|||
* EmbedSetting is used for embedding Appsmith apps on other platforms
|
||||
*/
|
||||
@Data
|
||||
public static class EmbedSetting {
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String height;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String width;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showNavigationBar;
|
||||
}
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class EmbedSetting extends EmbedSettingCE {}
|
||||
|
||||
/**
|
||||
* NavigationSetting stores the navigation configuration for the app
|
||||
*/
|
||||
@Data
|
||||
public static class NavigationSetting {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showNavbar;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String orientation;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String navStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String position;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String itemStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String colorStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String logoAssetId;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String logoConfiguration;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showSignIn;
|
||||
}
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class NavigationSetting extends NavigationSettingCE {}
|
||||
|
||||
/**
|
||||
* AppPositioning captures widget positioning Mode of the application
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class AppPositioning {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Type type;
|
||||
|
||||
public static class AppPositioning extends AppPositioningCE {
|
||||
public AppPositioning(String type) {
|
||||
setType(Type.valueOf(type));
|
||||
super(type);
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
FIXED,
|
||||
AUTO,
|
||||
ANVIL
|
||||
public AppPositioning(AppPositioning.Type type) {
|
||||
super(type);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
public static class ThemeSetting {
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String accentColor;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String borderRadius;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private float sizing = 1;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private float density = 1;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String fontFamily;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Type colorMode;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
IconStyle iconStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
AppMaxWidth appMaxWidth = AppMaxWidth.LARGE;
|
||||
|
||||
public static class ThemeSetting extends ThemeSettingCE {
|
||||
public ThemeSetting(Type colorMode) {
|
||||
this.colorMode = colorMode;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
LIGHT,
|
||||
DARK
|
||||
}
|
||||
|
||||
public enum IconStyle {
|
||||
OUTLINED,
|
||||
FILLED
|
||||
}
|
||||
|
||||
public enum AppMaxWidth {
|
||||
UNLIMITED,
|
||||
LARGE,
|
||||
MEDIUM,
|
||||
super(colorMode);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Fields extends BaseDomain.Fields {
|
||||
public static final String gitApplicationMetadata_gitAuth =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.gitAuth);
|
||||
public static final String gitApplicationMetadata_defaultApplicationId =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.defaultApplicationId);
|
||||
|
||||
public static final String gitApplicationMetadata_defaultArtifactId =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.defaultArtifactId);
|
||||
public static final String gitApplicationMetadata_isAutoDeploymentEnabled =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isAutoDeploymentEnabled);
|
||||
public static final String gitApplicationMetadata_branchName =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.branchName);
|
||||
public static final String gitApplicationMetadata_isRepoPrivate =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isRepoPrivate);
|
||||
public static final String gitApplicationMetadata_isProtectedBranch =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isProtectedBranch);
|
||||
}
|
||||
public static class Fields extends ApplicationCE.Fields {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,124 +1,15 @@
|
|||
package com.appsmith.server.domains;
|
||||
|
||||
import com.appsmith.external.models.AppsmithDomain;
|
||||
import com.appsmith.external.views.Views;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import com.appsmith.server.domains.ce.GitArtifactMetadataCE;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// This class will be used for one-to-one mapping for the DB application and the application present in the git repo.
|
||||
@Data
|
||||
@FieldNameConstants
|
||||
public class GitArtifactMetadata implements AppsmithDomain {
|
||||
// Git branch corresponding to this application, we have one to one mapping for application in DB with git-branch
|
||||
@JsonView(Views.Public.class)
|
||||
String branchName;
|
||||
|
||||
// Git default branch corresponding to the remote git repo to which the application is connected to
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultBranchName;
|
||||
|
||||
// Git remote url will be used while pushing and pulling changes
|
||||
@JsonView(Views.Public.class)
|
||||
String remoteUrl;
|
||||
|
||||
// Git remote https url will be used while checking if the repo is public or private
|
||||
@JsonView(Views.Public.class)
|
||||
String browserSupportedRemoteUrl;
|
||||
|
||||
// If remote repo is private and will be stored only with default application
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isRepoPrivate;
|
||||
|
||||
// The name of git repo
|
||||
@JsonView(Views.Public.class)
|
||||
String repoName;
|
||||
|
||||
// Default application id used for storing the application files in local volume :
|
||||
// container-volumes/git_repo/workspaceId/defaultApplicationId/branchName/applicationDirectoryStructure...
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultApplicationId;
|
||||
|
||||
// We are maintaining this attribute separately from defaultApplicationId to maintain backward compatibility with
|
||||
// the directory structure that folks might on their file systems
|
||||
// Default artifact id used for storing the artifact files in local volume :
|
||||
// container-volumes/git_repo/workspaceId/artifactType/defaultArtifactId/branchName/artifactDirectoryStructure...
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultArtifactId;
|
||||
|
||||
// Git credentials used to push changes to remote repo and will be stored with default application only to optimise
|
||||
// space requirement and update operation
|
||||
@JsonView(Views.Internal.class)
|
||||
GitAuth gitAuth;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
Map<String, GitProfile> gitProfiles;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
String publicKey;
|
||||
|
||||
// Deploy key documentation url
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
String docUrl;
|
||||
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssX", timezone = "UTC")
|
||||
@JsonView(Views.Public.class)
|
||||
Instant lastCommittedAt;
|
||||
|
||||
@JsonView(Views.Metadata.class)
|
||||
List<String> branchProtectionRules;
|
||||
|
||||
/**
|
||||
* This field is no more used and will be removed in future version.
|
||||
* Please use the branchProtectionRules field to know whether a branch is protected or not.
|
||||
*/
|
||||
@Deprecated
|
||||
@JsonView(Views.Internal.class)
|
||||
Boolean isProtectedBranch;
|
||||
|
||||
@JsonView(Views.Metadata.class)
|
||||
AutoCommitConfig autoCommitConfig;
|
||||
|
||||
/**
|
||||
* Boolean flag to store whether auto deployment is enabled for any branch of this application.
|
||||
* If true, any branch of this application can be automatically deployed using git web hook.
|
||||
*/
|
||||
@JsonView(Views.Metadata.class)
|
||||
boolean isAutoDeploymentEnabled;
|
||||
|
||||
public AutoCommitConfig getAutoCommitConfig() {
|
||||
// by default, the auto commit should be enabled.
|
||||
// new AutoCommitConfig will have enabled=true so we're returning a new object when field is null
|
||||
if (autoCommitConfig == null) {
|
||||
autoCommitConfig = new AutoCommitConfig();
|
||||
}
|
||||
return autoCommitConfig;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
public String getDefaultArtifactId() {
|
||||
if (StringUtils.hasText(defaultArtifactId)) {
|
||||
return defaultArtifactId;
|
||||
} else return defaultApplicationId;
|
||||
}
|
||||
|
||||
// TODO : Set to private to prevent direct access unless migration is performed
|
||||
private void setDefaultArtifactId(String defaultArtifactId) {
|
||||
this.defaultArtifactId = defaultArtifactId;
|
||||
}
|
||||
|
||||
public void setDefaultApplicationId(String defaultApplicationId) {
|
||||
this.defaultApplicationId = defaultApplicationId;
|
||||
this.defaultArtifactId = defaultApplicationId;
|
||||
}
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GitArtifactMetadata extends GitArtifactMetadataCE implements AppsmithDomain {
|
||||
public static class Fields extends GitArtifactMetadataCE.Fields {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,525 @@
|
|||
package com.appsmith.server.domains.ce;
|
||||
|
||||
import com.appsmith.external.models.BaseDomain;
|
||||
import com.appsmith.external.views.Git;
|
||||
import com.appsmith.external.views.Views;
|
||||
import com.appsmith.server.constants.ArtifactType;
|
||||
import com.appsmith.server.domains.Application;
|
||||
import com.appsmith.server.domains.ApplicationDetail;
|
||||
import com.appsmith.server.domains.ApplicationPage;
|
||||
import com.appsmith.server.domains.GitArtifactMetadata;
|
||||
import com.appsmith.server.dtos.CustomJSLibContextDTO;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.appsmith.external.helpers.StringUtils.dotted;
|
||||
import static com.appsmith.server.constants.ResourceModes.EDIT;
|
||||
import static com.appsmith.server.constants.ResourceModes.VIEW;
|
||||
import static com.appsmith.server.helpers.DateUtils.ISO_FORMATTER;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@Document
|
||||
@FieldNameConstants
|
||||
public class ApplicationCE extends BaseDomain implements ArtifactCE {
|
||||
|
||||
@NotNull @JsonView(Views.Public.class)
|
||||
String name;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
String workspaceId;
|
||||
|
||||
// TODO: remove default values from application
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@Deprecated(forRemoval = true)
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isPublic = false;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
List<ApplicationPage> pages;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
List<ApplicationPage> publishedPages;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Transient
|
||||
Boolean viewMode = false;
|
||||
|
||||
@Transient
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
boolean appIsExample = false;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
long unreadCommentThreads;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String clonedFromApplicationId;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
ApplicationDetail unpublishedApplicationDetail;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
ApplicationDetail publishedApplicationDetail;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
String color;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
String icon;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
private String slug;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
Application.AppLayout unpublishedAppLayout;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
Application.AppLayout publishedAppLayout;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Set<CustomJSLibContextDTO> unpublishedCustomJSLibs;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Set<CustomJSLibContextDTO> publishedCustomJSLibs;
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
GitArtifactMetadata gitApplicationMetadata;
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView(Views.Public.class)
|
||||
Instant lastDeployedAt; // when this application was last deployed
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Integer evaluationVersion;
|
||||
|
||||
/**
|
||||
* applicationVersion will be used when we've a breaking change in application, and it's not possible to write a
|
||||
* migration. User need to update the application manually.
|
||||
* In such cases, we can use this field to determine whether we need to notify user about that breaking change
|
||||
* so that they can update their application.
|
||||
* Once updated, we should set applicationVersion to latest version as well.
|
||||
*/
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Integer applicationVersion;
|
||||
|
||||
/**
|
||||
* Changing name, change in pages, widgets and datasources will set lastEditedAt.
|
||||
* Other activities e.g. changing policy will not change this property.
|
||||
* We're adding JsonIgnore here because it'll be exposed as modifiedAt to keep it backward compatible
|
||||
*/
|
||||
@JsonView(Views.Internal.class)
|
||||
Instant lastEditedAt;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Application.EmbedSetting embedSetting;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
Boolean collapseInvisibleWidgets;
|
||||
|
||||
/**
|
||||
* Earlier this was returning value of the updatedAt property in the base domain.
|
||||
* As this property is modified by the framework when there is any change in domain,
|
||||
* a new property lastEditedAt has been added to track the edit actions from users.
|
||||
* This method exposes that property.
|
||||
*
|
||||
* @return updated time as a string
|
||||
*/
|
||||
@JsonProperty(value = "modifiedAt", access = JsonProperty.Access.READ_ONLY)
|
||||
@JsonView(Views.Public.class)
|
||||
public String getLastUpdateTime() {
|
||||
if (lastEditedAt != null) {
|
||||
return ISO_FORMATTER.format(lastEditedAt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
public String getLastDeployedAt() {
|
||||
if (lastDeployedAt != null) {
|
||||
return ISO_FORMATTER.format(lastDeployedAt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean forkingEnabled;
|
||||
|
||||
// Field to convey if the application is updated by the user
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isManualUpdate;
|
||||
|
||||
// Field to convey if the application is modified from the DB migration
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isAutoUpdate;
|
||||
|
||||
// To convey current schema version for client and server. This will be used to check if we run the migration
|
||||
// between 2 commits if the application is connected to git
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
Integer clientSchemaVersion;
|
||||
|
||||
@JsonView({Views.Internal.class, Git.class})
|
||||
Integer serverSchemaVersion;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String publishedModeThemeId;
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
String editModeThemeId;
|
||||
|
||||
// TODO Temporary provision for exporting the application with datasource configuration for the sample/template apps
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean exportWithConfiguration;
|
||||
|
||||
// forkWithConfiguration represents whether credentials are shared or not while forking an app
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean forkWithConfiguration;
|
||||
|
||||
// isCommunityTemplate represents whether this application has been published as a community template
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isCommunityTemplate;
|
||||
|
||||
/* Template title of the template from which this app was forked, if any */
|
||||
@JsonView(Views.Public.class)
|
||||
String forkedFromTemplateTitle;
|
||||
|
||||
// This constructor is used during clone application. It only deeply copies selected fields. The rest are either
|
||||
// initialized newly or is left up to the calling function to set.
|
||||
public ApplicationCE(ApplicationCE application) {
|
||||
super();
|
||||
this.workspaceId = application.getWorkspaceId();
|
||||
this.pages = new ArrayList<>();
|
||||
this.publishedPages = new ArrayList<>();
|
||||
this.clonedFromApplicationId = application.getId();
|
||||
this.color = application.getColor();
|
||||
this.icon = application.getIcon();
|
||||
this.unpublishedAppLayout = application.getUnpublishedAppLayout() == null
|
||||
? null
|
||||
: new Application.AppLayout(application.getUnpublishedAppLayout().type);
|
||||
this.publishedAppLayout = application.getPublishedAppLayout() == null
|
||||
? null
|
||||
: new Application.AppLayout(application.getPublishedAppLayout().type);
|
||||
this.setUnpublishedApplicationDetail(new ApplicationDetail());
|
||||
this.setPublishedApplicationDetail(new ApplicationDetail());
|
||||
if (application.getUnpublishedApplicationDetail() == null) {
|
||||
application.setUnpublishedApplicationDetail(new ApplicationDetail());
|
||||
}
|
||||
if (application.getPublishedApplicationDetail() == null) {
|
||||
application.setPublishedApplicationDetail(new ApplicationDetail());
|
||||
}
|
||||
|
||||
Application.AppPositioning unpublishedAppPositioning =
|
||||
application.getUnpublishedApplicationDetail().getAppPositioning() == null
|
||||
? null
|
||||
: new Application.AppPositioning(
|
||||
application.getUnpublishedApplicationDetail().getAppPositioning().type);
|
||||
this.getUnpublishedApplicationDetail().setAppPositioning(unpublishedAppPositioning);
|
||||
Application.AppPositioning publishedAppPositioning =
|
||||
application.getPublishedApplicationDetail().getAppPositioning() == null
|
||||
? null
|
||||
: new Application.AppPositioning(
|
||||
application.getPublishedApplicationDetail().getAppPositioning().type);
|
||||
this.getPublishedApplicationDetail().setAppPositioning(publishedAppPositioning);
|
||||
this.getUnpublishedApplicationDetail()
|
||||
.setNavigationSetting(
|
||||
application.getUnpublishedApplicationDetail().getNavigationSetting() == null
|
||||
? null
|
||||
: new Application.NavigationSetting());
|
||||
this.getPublishedApplicationDetail()
|
||||
.setNavigationSetting(
|
||||
application.getPublishedApplicationDetail().getNavigationSetting() == null
|
||||
? null
|
||||
: new Application.NavigationSetting());
|
||||
this.getUnpublishedApplicationDetail()
|
||||
.setThemeSetting(
|
||||
application.getUnpublishedApplicationDetail().getThemeSetting() == null
|
||||
? null
|
||||
: new Application.ThemeSetting());
|
||||
this.getPublishedApplicationDetail()
|
||||
.setThemeSetting(
|
||||
application.getPublishedApplicationDetail().getThemeSetting() == null
|
||||
? null
|
||||
: new Application.ThemeSetting());
|
||||
this.unpublishedCustomJSLibs = application.getUnpublishedCustomJSLibs();
|
||||
this.collapseInvisibleWidgets = application.getCollapseInvisibleWidgets();
|
||||
}
|
||||
|
||||
public void exportApplicationPages(final Map<String, String> pageIdToNameMap) {
|
||||
for (ApplicationPage applicationPage : this.getPages()) {
|
||||
applicationPage.setId(pageIdToNameMap.get(applicationPage.getId() + EDIT));
|
||||
applicationPage.setDefaultPageId(null);
|
||||
}
|
||||
for (ApplicationPage applicationPage : this.getPublishedPages()) {
|
||||
applicationPage.setId(pageIdToNameMap.get(applicationPage.getId() + VIEW));
|
||||
applicationPage.setDefaultPageId(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseId() {
|
||||
if (this.getGitArtifactMetadata() != null
|
||||
&& StringUtils.hasLength(this.getGitArtifactMetadata().getDefaultArtifactId())) {
|
||||
return this.getGitArtifactMetadata().getDefaultArtifactId();
|
||||
}
|
||||
return ArtifactCE.super.getBaseId();
|
||||
}
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Override
|
||||
public GitArtifactMetadata getGitArtifactMetadata() {
|
||||
return this.gitApplicationMetadata;
|
||||
}
|
||||
|
||||
@JsonView(Views.Internal.class)
|
||||
@Override
|
||||
public void setGitArtifactMetadata(GitArtifactMetadata gitArtifactMetadata) {
|
||||
this.gitApplicationMetadata = gitArtifactMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnpublishedThemeId() {
|
||||
return this.getEditModeThemeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnpublishedThemeId(String themeId) {
|
||||
this.setEditModeThemeId(themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublishedThemeId() {
|
||||
return this.getPublishedModeThemeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublishedThemeId(String themeId) {
|
||||
this.setPublishedModeThemeId(themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sanitiseToExportDBObject() {
|
||||
this.setWorkspaceId(null);
|
||||
this.setModifiedBy(null);
|
||||
this.setCreatedBy(null);
|
||||
this.setLastDeployedAt(null);
|
||||
this.setLastEditedAt(null);
|
||||
this.setGitApplicationMetadata(null);
|
||||
this.setEditModeThemeId(null);
|
||||
this.setPublishedModeThemeId(null);
|
||||
this.setClientSchemaVersion(null);
|
||||
this.setServerSchemaVersion(null);
|
||||
this.setIsManualUpdate(false);
|
||||
this.setPublishedCustomJSLibs(new HashSet<>());
|
||||
this.setExportWithConfiguration(null);
|
||||
this.setForkWithConfiguration(null);
|
||||
this.setForkingEnabled(null);
|
||||
super.sanitiseToExportDBObject();
|
||||
}
|
||||
|
||||
public List<ApplicationPage> getPages() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedPages : pages;
|
||||
}
|
||||
|
||||
public Application.AppLayout getAppLayout() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedAppLayout : unpublishedAppLayout;
|
||||
}
|
||||
|
||||
public void setAppLayout(Application.AppLayout appLayout) {
|
||||
if (Boolean.TRUE.equals(viewMode)) {
|
||||
publishedAppLayout = appLayout;
|
||||
} else {
|
||||
unpublishedAppLayout = appLayout;
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationDetail getApplicationDetail() {
|
||||
return Boolean.TRUE.equals(viewMode) ? publishedApplicationDetail : unpublishedApplicationDetail;
|
||||
}
|
||||
|
||||
public void setApplicationDetail(ApplicationDetail applicationDetail) {
|
||||
if (Boolean.TRUE.equals(viewMode)) {
|
||||
publishedApplicationDetail = applicationDetail;
|
||||
} else {
|
||||
unpublishedApplicationDetail = applicationDetail;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonView({Views.Internal.class})
|
||||
public ArtifactType getArtifactType() {
|
||||
return ArtifactType.APPLICATION;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class AppLayoutCE implements Serializable {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
protected Type type;
|
||||
|
||||
public enum Type {
|
||||
DESKTOP,
|
||||
TABLET_LARGE,
|
||||
TABLET,
|
||||
MOBILE,
|
||||
FLUID,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EmbedSetting is used for embedding Appsmith apps on other platforms
|
||||
*/
|
||||
@Data
|
||||
public static class EmbedSettingCE {
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String height;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String width;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showNavigationBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* NavigationSetting stores the navigation configuration for the app
|
||||
*/
|
||||
@Data
|
||||
public static class NavigationSettingCE {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showNavbar;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String orientation;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String navStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String position;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String itemStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String colorStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String logoAssetId;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String logoConfiguration;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private Boolean showSignIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* AppPositioning captures widget positioning Mode of the application
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class AppPositioningCE {
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
protected Type type;
|
||||
|
||||
public AppPositioningCE(String type) {
|
||||
setType(Type.valueOf(type));
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
FIXED,
|
||||
AUTO,
|
||||
ANVIL
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class ThemeSettingCE {
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String accentColor;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String borderRadius;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private float sizing = 1;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private float density = 1;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
private String fontFamily;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
protected Type colorMode;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
IconStyle iconStyle;
|
||||
|
||||
@JsonView({Views.Public.class, Git.class})
|
||||
AppMaxWidth appMaxWidth = AppMaxWidth.LARGE;
|
||||
|
||||
public ThemeSettingCE(Type colorMode) {
|
||||
this.colorMode = colorMode;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
LIGHT,
|
||||
DARK
|
||||
}
|
||||
|
||||
public enum IconStyle {
|
||||
OUTLINED,
|
||||
FILLED
|
||||
}
|
||||
|
||||
public enum AppMaxWidth {
|
||||
UNLIMITED,
|
||||
LARGE,
|
||||
MEDIUM,
|
||||
}
|
||||
}
|
||||
|
||||
public static class Fields extends BaseDomain.Fields {
|
||||
public static final String gitApplicationMetadata_gitAuth =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.gitAuth);
|
||||
public static final String gitApplicationMetadata_defaultApplicationId =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.defaultApplicationId);
|
||||
public static final String gitApplicationMetadata_defaultArtifactId =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.defaultArtifactId);
|
||||
public static final String gitApplicationMetadata_branchName =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.branchName);
|
||||
public static final String gitApplicationMetadata_isRepoPrivate =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isRepoPrivate);
|
||||
public static final String gitApplicationMetadata_isProtectedBranch =
|
||||
dotted(gitApplicationMetadata, GitArtifactMetadata.Fields.isProtectedBranch);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package com.appsmith.server.domains.ce;
|
||||
|
||||
import com.appsmith.external.models.AppsmithDomain;
|
||||
import com.appsmith.external.views.Views;
|
||||
import com.appsmith.server.domains.AutoCommitConfig;
|
||||
import com.appsmith.server.domains.GitAuth;
|
||||
import com.appsmith.server.domains.GitProfile;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// This class will be used for one-to-one mapping for the DB application and the application present in the git repo.
|
||||
@Data
|
||||
@FieldNameConstants
|
||||
public class GitArtifactMetadataCE implements AppsmithDomain {
|
||||
// Git branch corresponding to this application, we have one to one mapping for application in DB with git-branch
|
||||
@JsonView(Views.Public.class)
|
||||
String branchName;
|
||||
|
||||
// Git default branch corresponding to the remote git repo to which the application is connected to
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultBranchName;
|
||||
|
||||
// Git remote url will be used while pushing and pulling changes
|
||||
@JsonView(Views.Public.class)
|
||||
String remoteUrl;
|
||||
|
||||
// Git remote https url will be used while checking if the repo is public or private
|
||||
@JsonView(Views.Public.class)
|
||||
String browserSupportedRemoteUrl;
|
||||
|
||||
// If remote repo is private and will be stored only with default application
|
||||
@JsonView(Views.Public.class)
|
||||
Boolean isRepoPrivate;
|
||||
|
||||
// The name of git repo
|
||||
@JsonView(Views.Public.class)
|
||||
String repoName;
|
||||
|
||||
// Default application id used for storing the application files in local volume :
|
||||
// container-volumes/git_repo/workspaceId/defaultApplicationId/branchName/applicationDirectoryStructure...
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultApplicationId;
|
||||
|
||||
// We are maintaining this attribute separately from defaultApplicationId to maintain backward compatibility with
|
||||
// the directory structure that folks might on their file systems
|
||||
// Default artifact id used for storing the artifact files in local volume :
|
||||
// container-volumes/git_repo/workspaceId/artifactType/defaultArtifactId/branchName/artifactDirectoryStructure...
|
||||
@JsonView(Views.Public.class)
|
||||
String defaultArtifactId;
|
||||
|
||||
// Git credentials used to push changes to remote repo and will be stored with default application only to optimise
|
||||
// space requirement and update operation
|
||||
@JsonView(Views.Internal.class)
|
||||
GitAuth gitAuth;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
Map<String, GitProfile> gitProfiles;
|
||||
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
String publicKey;
|
||||
|
||||
// Deploy key documentation url
|
||||
@Transient
|
||||
@JsonView(Views.Public.class)
|
||||
String docUrl;
|
||||
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssX", timezone = "UTC")
|
||||
@JsonView(Views.Public.class)
|
||||
Instant lastCommittedAt;
|
||||
|
||||
@JsonView(Views.Metadata.class)
|
||||
List<String> branchProtectionRules;
|
||||
|
||||
/**
|
||||
* This field is no more used and will be removed in future version.
|
||||
* Please use the branchProtectionRules field to know whether a branch is protected or not.
|
||||
*/
|
||||
@Deprecated
|
||||
@JsonView(Views.Internal.class)
|
||||
Boolean isProtectedBranch;
|
||||
|
||||
@JsonView(Views.Metadata.class)
|
||||
AutoCommitConfig autoCommitConfig;
|
||||
|
||||
public AutoCommitConfig getAutoCommitConfig() {
|
||||
// by default, the auto commit should be enabled.
|
||||
// new AutoCommitConfig will have enabled=true so we're returning a new object when field is null
|
||||
if (autoCommitConfig == null) {
|
||||
autoCommitConfig = new AutoCommitConfig();
|
||||
}
|
||||
return autoCommitConfig;
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
public String getDefaultArtifactId() {
|
||||
if (StringUtils.hasText(defaultArtifactId)) {
|
||||
return defaultArtifactId;
|
||||
} else return defaultApplicationId;
|
||||
}
|
||||
|
||||
// TODO : Set to private to prevent direct access unless migration is performed
|
||||
private void setDefaultArtifactId(String defaultArtifactId) {
|
||||
this.defaultArtifactId = defaultArtifactId;
|
||||
}
|
||||
|
||||
public void setDefaultApplicationId(String defaultApplicationId) {
|
||||
this.defaultApplicationId = defaultApplicationId;
|
||||
this.defaultArtifactId = defaultApplicationId;
|
||||
}
|
||||
|
||||
public static class Fields {}
|
||||
}
|
||||
|
|
@ -18,7 +18,11 @@ public class EqualityTest {
|
|||
|
||||
private final Set<Class<?>> TESTED_CLASSES = Set.of(
|
||||
// Note: Adding a class here means that we have a test for its equality in this file.
|
||||
ApplicationDetail.class, TenantConfiguration.class);
|
||||
ApplicationDetail.class,
|
||||
TenantConfiguration.class,
|
||||
Application.AppLayout.class,
|
||||
Application.EmbedSetting.class,
|
||||
GitArtifactMetadata.class);
|
||||
|
||||
@SneakyThrows
|
||||
@Test
|
||||
|
|
@ -72,4 +76,55 @@ public class EqualityTest {
|
|||
assertThat(d1).isEqualTo(d2);
|
||||
assertThat(d1).isNotEqualTo(d3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAppLayout() {
|
||||
Application.AppLayout a1 = new Application.AppLayout(Application.AppLayout.Type.DESKTOP);
|
||||
Application.AppLayout a2 = new Application.AppLayout(Application.AppLayout.Type.DESKTOP);
|
||||
Application.AppLayout a3 = new Application.AppLayout(Application.AppLayout.Type.MOBILE);
|
||||
assertThat(a1).isEqualTo(a2).isNotEqualTo(a3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAppEmbedSetting() {
|
||||
Application.EmbedSetting a1 = new Application.EmbedSetting();
|
||||
a1.setHeight("5");
|
||||
a1.setWidth("5");
|
||||
a1.setShowNavigationBar(Boolean.TRUE);
|
||||
Application.EmbedSetting a2 = new Application.EmbedSetting();
|
||||
a2.setHeight("5");
|
||||
a2.setWidth("5");
|
||||
a2.setShowNavigationBar(Boolean.TRUE);
|
||||
Application.EmbedSetting a3 = new Application.EmbedSetting();
|
||||
a3.setHeight("5");
|
||||
a3.setWidth("5");
|
||||
a3.setShowNavigationBar(Boolean.FALSE);
|
||||
assertThat(a1).isEqualTo(a2).isNotEqualTo(a3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArtifactEquality() {
|
||||
String remoteUrl1 = "protocol://domain.superdomain";
|
||||
String remoteUrl2 = "protocol://domain.superdomain2";
|
||||
|
||||
GitArtifactMetadata a1 = new GitArtifactMetadata();
|
||||
a1.setRemoteUrl(remoteUrl1);
|
||||
GitArtifactMetadata a2 = new GitArtifactMetadata();
|
||||
a2.setRemoteUrl(remoteUrl1);
|
||||
GitArtifactMetadata a3 = new GitArtifactMetadata();
|
||||
a3.setRemoteUrl(remoteUrl2);
|
||||
|
||||
assertThat(a1).isEqualTo(a2).isNotEqualTo(a3);
|
||||
|
||||
a1.setAutoCommitConfig(new AutoCommitConfig());
|
||||
a2.setAutoCommitConfig(new AutoCommitConfig());
|
||||
a3.setAutoCommitConfig(new AutoCommitConfig());
|
||||
|
||||
assertThat(a1).isEqualTo(a2).isNotEqualTo(a3);
|
||||
|
||||
a1.getAutoCommitConfig().setEnabled(Boolean.TRUE);
|
||||
a2.getAutoCommitConfig().setEnabled(Boolean.FALSE);
|
||||
|
||||
assertThat(a1).isNotEqualTo(a2).isNotEqualTo(a3);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user