Add more devices in AppLayout options (#3451)
* Remove width and introduce more AppLayout type enums * Fix: Adding min width to layout options. Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com>
This commit is contained in:
parent
f5ec68edfe
commit
65568a4e13
|
|
@ -17,7 +17,7 @@ describe("Dynamic Layout Functionality", function() {
|
|||
.click({ force: true });
|
||||
cy.get(commonlocators.canvas)
|
||||
.invoke("width")
|
||||
.should("be.eq", 720);
|
||||
.should("be.eq", 450);
|
||||
});
|
||||
it("Dynamic Layout - New Page should have selected Layout", function() {
|
||||
cy.get(pages.AddPage)
|
||||
|
|
@ -25,6 +25,6 @@ describe("Dynamic Layout Functionality", function() {
|
|||
.click();
|
||||
cy.get(commonlocators.canvas)
|
||||
.invoke("width")
|
||||
.should("be.eq", 720);
|
||||
.should("be.eq", 450);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import localStorage from "utils/localStorage";
|
||||
|
||||
export const CANVAS_DEFAULT_WIDTH_PX = 1224;
|
||||
export const CANVAS_TABLET_WIDTH_PX = 1024;
|
||||
export const CANVAS_MOBILE_WIDTH_PX = 720;
|
||||
export const CANVAS_DEFAULT_HEIGHT_PX = 1292;
|
||||
export const CANVAS_DEFAULT_GRID_HEIGHT_PX = 1;
|
||||
export const CANVAS_DEFAULT_GRID_WIDTH_PX = 1;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { SupportedLayouts } from "reducers/entityReducers/pageListReducer";
|
||||
|
||||
export enum WidgetTypes {
|
||||
BUTTON_WIDGET = "BUTTON_WIDGET",
|
||||
TEXT_WIDGET = "TEXT_WIDGET",
|
||||
|
|
@ -71,6 +73,27 @@ export const CSSUnits: { [id: string]: CSSUnit } = {
|
|||
RELATIVE_PARENT: "%",
|
||||
};
|
||||
|
||||
interface LayoutConfig {
|
||||
minWidth: number;
|
||||
maxWidth: number;
|
||||
}
|
||||
|
||||
type LayoutConfigurations = Record<SupportedLayouts, LayoutConfig>;
|
||||
export const DefaultLayoutType: SupportedLayouts = "DESKTOP";
|
||||
export const layoutConfigurations: LayoutConfigurations = {
|
||||
TABLET_LARGE: {
|
||||
minWidth: 960,
|
||||
maxWidth: 1080,
|
||||
},
|
||||
MOBILE: {
|
||||
minWidth: 350,
|
||||
maxWidth: 450,
|
||||
},
|
||||
DESKTOP: { minWidth: 1160, maxWidth: 1280 },
|
||||
TABLET: { minWidth: 650, maxWidth: 800 },
|
||||
FLUID: { minWidth: -1, maxWidth: -1 },
|
||||
};
|
||||
|
||||
export const GridDefaults = {
|
||||
DEFAULT_CELL_SIZE: 1,
|
||||
DEFAULT_WIDGET_WIDTH: 200,
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
import { updateApplicationLayout } from "actions/applicationActions";
|
||||
import Dropdown from "components/ads/Dropdown";
|
||||
import Icon, { IconName, IconSize } from "components/ads/Icon";
|
||||
import {
|
||||
CANVAS_DEFAULT_WIDTH_PX,
|
||||
CANVAS_MOBILE_WIDTH_PX,
|
||||
CANVAS_TABLET_WIDTH_PX,
|
||||
} from "constants/AppConstants";
|
||||
import { Colors } from "constants/Colors";
|
||||
import React from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { AppState } from "reducers";
|
||||
import {
|
||||
AppLayoutConfig,
|
||||
AppLayoutType,
|
||||
SupportedLayouts,
|
||||
} from "reducers/entityReducers/pageListReducer";
|
||||
import {
|
||||
getCurrentApplicationId,
|
||||
|
|
@ -23,17 +18,14 @@ import { useSelector } from "store";
|
|||
import styled, { ThemeProvider } from "styled-components";
|
||||
import { noop } from "utils/AppsmithUtils";
|
||||
|
||||
type SupportedLayouts = "Desktop" | "Tablet" | "Mobile Device" | "Fluid Width";
|
||||
interface AppsmithLayoutConfigOption {
|
||||
name: SupportedLayouts;
|
||||
type: AppLayoutType;
|
||||
width: number;
|
||||
name: string;
|
||||
type: SupportedLayouts;
|
||||
icon?: IconName;
|
||||
}
|
||||
|
||||
export const AppsmithDefaultLayout: AppLayoutConfig = {
|
||||
type: "FLUID",
|
||||
width: CANVAS_DEFAULT_WIDTH_PX,
|
||||
type: "DESKTOP",
|
||||
};
|
||||
|
||||
const AppsmithLayouts: AppsmithLayoutConfigOption[] = [
|
||||
|
|
@ -42,22 +34,24 @@ const AppsmithLayouts: AppsmithLayoutConfigOption[] = [
|
|||
...AppsmithDefaultLayout,
|
||||
icon: "desktop",
|
||||
},
|
||||
{
|
||||
name: "Tablet(Large)",
|
||||
type: "TABLET_LARGE",
|
||||
icon: "tablet",
|
||||
},
|
||||
{
|
||||
name: "Tablet",
|
||||
type: "FLUID",
|
||||
width: CANVAS_TABLET_WIDTH_PX,
|
||||
type: "TABLET",
|
||||
icon: "tablet",
|
||||
},
|
||||
{
|
||||
name: "Mobile Device",
|
||||
type: "FLUID",
|
||||
width: CANVAS_MOBILE_WIDTH_PX,
|
||||
type: "MOBILE",
|
||||
icon: "mobile",
|
||||
},
|
||||
{
|
||||
name: "Fluid Width",
|
||||
type: "FLUID",
|
||||
width: -1,
|
||||
icon: "fluid",
|
||||
},
|
||||
];
|
||||
|
|
@ -100,15 +94,11 @@ export const MainContainerLayoutControl: React.FC<any> = () => {
|
|||
onSelect: () =>
|
||||
updateAppLayout({
|
||||
type: each.type,
|
||||
width: each.width,
|
||||
}),
|
||||
};
|
||||
});
|
||||
const selectedLayout = appLayout
|
||||
? layoutOptions.find(
|
||||
(each) =>
|
||||
each.type === appLayout.type && each.width === appLayout.width,
|
||||
)
|
||||
? layoutOptions.find((each) => each.type === appLayout.type)
|
||||
: layoutOptions[0];
|
||||
const dispatch = useDispatch();
|
||||
const lightTheme = useSelector((state: AppState) =>
|
||||
|
|
@ -116,12 +106,11 @@ export const MainContainerLayoutControl: React.FC<any> = () => {
|
|||
);
|
||||
|
||||
const updateAppLayout = (layoutConfig: AppLayoutConfig) => {
|
||||
const { type, width } = layoutConfig;
|
||||
const { type } = layoutConfig;
|
||||
dispatch(
|
||||
updateApplicationLayout(appId || "", {
|
||||
appLayout: {
|
||||
type,
|
||||
width,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -105,10 +105,14 @@ export const pageListReducer = createReducer(initialState, {
|
|||
},
|
||||
});
|
||||
|
||||
export type AppLayoutType = "FIXED" | "FLUID";
|
||||
export type SupportedLayouts =
|
||||
| "DESKTOP"
|
||||
| "TABLET_LARGE"
|
||||
| "TABLET"
|
||||
| "MOBILE"
|
||||
| "FLUID";
|
||||
export interface AppLayoutConfig {
|
||||
type: AppLayoutType;
|
||||
width: number;
|
||||
type: SupportedLayouts;
|
||||
}
|
||||
|
||||
export interface PageListReduxState {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { theme } from "constants/DefaultTheme";
|
||||
import { ReduxActionTypes } from "constants/ReduxActionConstants";
|
||||
import {
|
||||
DefaultLayoutType,
|
||||
layoutConfigurations,
|
||||
} from "constants/WidgetConstants";
|
||||
import { debounce } from "lodash";
|
||||
import { AppsmithDefaultLayout } from "pages/Editor/MainContainerLayoutControl";
|
||||
import { useCallback, useEffect } from "react";
|
||||
|
|
@ -41,13 +45,17 @@ export const useDynamicAppLayout = () => {
|
|||
screenWidth: number,
|
||||
appLayout = AppsmithDefaultLayout,
|
||||
) => {
|
||||
const { type, width: layoutMaxWidth } = appLayout;
|
||||
const layoutWidth =
|
||||
type === "FLUID"
|
||||
? calculateFluidMaxWidth(screenWidth, layoutMaxWidth)
|
||||
: layoutMaxWidth;
|
||||
const { type } = appLayout;
|
||||
const { minWidth = -1, maxWidth = -1 } =
|
||||
layoutConfigurations[type] || layoutConfigurations[DefaultLayoutType];
|
||||
const calculatedMinWidth =
|
||||
appMode === "EDIT" ? minWidth - parseInt(theme.sidebarWidth) : minWidth;
|
||||
const layoutWidth = calculateFluidMaxWidth(screenWidth, maxWidth);
|
||||
const { rightColumn } = mainContainer;
|
||||
if (rightColumn !== layoutWidth) {
|
||||
if (
|
||||
(type === "FLUID" || calculatedMinWidth <= layoutWidth) &&
|
||||
rightColumn !== layoutWidth
|
||||
) {
|
||||
dispatch({
|
||||
type: ReduxActionTypes.UPDATE_CANVAS_LAYOUT,
|
||||
payload: {
|
||||
|
|
|
|||
|
|
@ -71,10 +71,8 @@ public class Application extends BaseDomain {
|
|||
this.clonedFromApplicationId = application.getId();
|
||||
this.color = application.getColor();
|
||||
this.icon = application.getIcon();
|
||||
this.unpublishedAppLayout = application.getUnpublishedAppLayout() == null ? null
|
||||
: new AppLayout(application.getUnpublishedAppLayout().type, application.getUnpublishedAppLayout().getWidth());
|
||||
this.publishedAppLayout = application.getPublishedAppLayout() == null ? null
|
||||
: new AppLayout(application.getPublishedAppLayout().type, application.getPublishedAppLayout().getWidth());
|
||||
this.unpublishedAppLayout = application.getUnpublishedAppLayout() == null ? null : new AppLayout(application.getUnpublishedAppLayout().type);
|
||||
this.publishedAppLayout = application.getPublishedAppLayout() == null ? null : new AppLayout(application.getPublishedAppLayout().type);
|
||||
}
|
||||
|
||||
public List<ApplicationPage> getPages() {
|
||||
|
|
@ -98,10 +96,24 @@ public class Application extends BaseDomain {
|
|||
@AllArgsConstructor
|
||||
public static class AppLayout implements Serializable {
|
||||
Type type;
|
||||
Integer width;
|
||||
|
||||
/**
|
||||
* @deprecated The following field is deprecated and now removed, because it's needed in a migration. After the
|
||||
* migration has been run, it may be removed (along with the migration or there'll be compile errors there).
|
||||
*/
|
||||
@JsonIgnore
|
||||
@Deprecated(forRemoval = true)
|
||||
Integer width = null;
|
||||
|
||||
public AppLayout(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
FIXED,
|
||||
DESKTOP,
|
||||
TABLET_LARGE,
|
||||
TABLET,
|
||||
MOBILE,
|
||||
FLUID,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.github.cloudyrock.mongock.ChangeLog;
|
||||
import com.github.cloudyrock.mongock.ChangeSet;
|
||||
import com.google.gson.Gson;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
|
|
@ -60,11 +61,13 @@ import org.springframework.dao.DuplicateKeyException;
|
|||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.index.CompoundIndexDefinition;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexOperations;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
|
@ -1916,4 +1919,78 @@ public class DatabaseChangelog {
|
|||
mongoTemplate.save(datasource);
|
||||
});
|
||||
}
|
||||
|
||||
@ChangeSet(order = "059", id = "change-applayout-type-definition", author = "")
|
||||
public void changeAppLayoutTypeDefinition(MongoOperations mongoOperations, MongoClient mongoClient) {
|
||||
// Unset an old version of this field, that is no longer used.
|
||||
mongoOperations.updateMulti(
|
||||
query(where("appLayout").exists(true)),
|
||||
new Update().unset("appLayout"),
|
||||
Application.class
|
||||
);
|
||||
|
||||
// For the published and unpublished app layouts, migrate the old way of specifying the device width to the new
|
||||
// way of doing it. Table of migrations:
|
||||
// Desktop: Old - 1224, New 1160 - 1280
|
||||
// Tablet L: Old - NA, New 960 - 1080
|
||||
// Tablet: Old - 1024, New 650 - 800
|
||||
// Mobile: Old - 720, New 350 - 450
|
||||
final Criteria criteria = new Criteria().orOperator(
|
||||
where(fieldName(QApplication.application.unpublishedAppLayout)).exists(true),
|
||||
where(fieldName(QApplication.application.publishedAppLayout)).exists(true)
|
||||
);
|
||||
|
||||
final Query query = query(criteria);
|
||||
query.fields()
|
||||
.include(fieldName(QApplication.application.unpublishedAppLayout))
|
||||
.include(fieldName(QApplication.application.publishedAppLayout));
|
||||
|
||||
List<Application> apps = mongoOperations.find(query, Application.class);
|
||||
|
||||
for (final Application app : apps) {
|
||||
final Integer unpublishedWidth = app.getUnpublishedAppLayout() == null ? null : app.getUnpublishedAppLayout().getWidth();
|
||||
final Integer publishedWidth = app.getPublishedAppLayout() == null ? null : app.getPublishedAppLayout().getWidth();
|
||||
final Update update = new Update().unset("unpublishedAppLayout.width").unset("publishedAppLayout.width");
|
||||
|
||||
if (unpublishedWidth != null) {
|
||||
final String typeField = "unpublishedAppLayout.type";
|
||||
if (unpublishedWidth == -1) {
|
||||
update.set(typeField, Application.AppLayout.Type.FLUID.name());
|
||||
} else {
|
||||
if (unpublishedWidth == 1024) {
|
||||
update.set(typeField, Application.AppLayout.Type.TABLET.name());
|
||||
} else if (unpublishedWidth == 720) {
|
||||
update.set(typeField, Application.AppLayout.Type.MOBILE.name());
|
||||
} else {
|
||||
// Default to Desktop.
|
||||
update.set(typeField, Application.AppLayout.Type.DESKTOP.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (publishedWidth != null) {
|
||||
final String typeField = "publishedAppLayout.type";
|
||||
if (publishedWidth == -1) {
|
||||
update.set(typeField, Application.AppLayout.Type.FLUID.name());
|
||||
} else {
|
||||
if (publishedWidth == 1024) {
|
||||
update.set(typeField, Application.AppLayout.Type.TABLET.name());
|
||||
} else if (publishedWidth == 720) {
|
||||
update.set(typeField, Application.AppLayout.Type.MOBILE.name());
|
||||
} else {
|
||||
// Default to Desktop.
|
||||
update.set(typeField, Application.AppLayout.Type.DESKTOP.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mongoOperations.updateFirst(
|
||||
query(where(fieldName(QApplication.application.id)).is(app.getId())),
|
||||
update,
|
||||
Application.class
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -697,7 +697,7 @@ public class ApplicationServiceTest {
|
|||
Application testApplication = new Application();
|
||||
String appName = "ApplicationServiceTest Publish Application";
|
||||
testApplication.setName(appName);
|
||||
testApplication.setAppLayout(new Application.AppLayout(Application.AppLayout.Type.FIXED, 1024));
|
||||
testApplication.setAppLayout(new Application.AppLayout(Application.AppLayout.Type.DESKTOP));
|
||||
Mono<Application> applicationMono = applicationPageService.createApplication(testApplication, orgId)
|
||||
.flatMap(application -> applicationPageService.publish(application.getId()))
|
||||
.then(applicationService.findByName(appName, MANAGE_APPLICATIONS))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user