Skip to content

Commit 9f76fda

Browse files
authored
Use 12-column layout for dashboard grid (#7396)
* Use 12-column layout for dashboard grid Set minSizeX, minSizeY for widgets to 2 since a value of 1 breaks all assumptions of the UI layout. Migration provide transition from 6 to 12 columns for all widgets. * Restyled by prettier
1 parent d8ae679 commit 9f76fda

File tree

13 files changed

+98
-83
lines changed

13 files changed

+98
-83
lines changed

client/app/components/dashboards/dashboard-grid.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
right: 0;
5252
background: linear-gradient(to bottom, transparent, transparent 2px, #f6f8f9 2px, #f6f8f9 5px),
5353
linear-gradient(to left, #b3babf, #b3babf 1px, transparent 1px, transparent);
54-
background-size: calc((100% + 15px) / 6) 5px;
54+
background-size: calc((100% + 15px) / 12) 5px;
5555
background-position: -7px 1px;
5656
}
5757
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
export default {
2-
columns: 6, // grid columns count
2+
columns: 12, // grid columns count
33
rowHeight: 50, // grid row height (incl. bottom padding)
44
margins: 15, // widget margins
55
mobileBreakPoint: 800,
66
// defaults for widgets
7-
defaultSizeX: 3,
7+
defaultSizeX: 6,
88
defaultSizeY: 3,
9-
minSizeX: 1,
10-
maxSizeX: 6,
11-
minSizeY: 1,
9+
minSizeX: 2,
10+
maxSizeX: 12,
11+
minSizeY: 2,
1212
maxSizeY: 1000,
1313
};

client/cypress/integration/dashboard/dashboard_spec.js

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe("Dashboard", () => {
2323
cy.getByTestId("DashboardSaveButton").click();
2424
});
2525

26-
cy.wait("@NewDashboard").then(xhr => {
26+
cy.wait("@NewDashboard").then((xhr) => {
2727
const id = Cypress._.get(xhr, "response.body.id");
2828
assert.isDefined(id, "Dashboard api call returns id");
2929

@@ -40,13 +40,9 @@ describe("Dashboard", () => {
4040

4141
cy.getByTestId("DashboardMoreButton").click();
4242

43-
cy.getByTestId("DashboardMoreButtonMenu")
44-
.contains("Archive")
45-
.click();
43+
cy.getByTestId("DashboardMoreButtonMenu").contains("Archive").click();
4644

47-
cy.get(".ant-modal .ant-btn")
48-
.contains("Archive")
49-
.click({ force: true });
45+
cy.get(".ant-modal .ant-btn").contains("Archive").click({ force: true });
5046
cy.get(".label-tag-archived").should("exist");
5147

5248
cy.visit("/dashboards");
@@ -60,7 +56,7 @@ describe("Dashboard", () => {
6056
cy.server();
6157
cy.route("GET", "**/api/dashboards/*").as("LoadDashboard");
6258
cy.createDashboard("Dashboard multiple urls").then(({ id, slug }) => {
63-
[`/dashboards/${id}`, `/dashboards/${id}-anything-here`, `/dashboard/${slug}`].forEach(url => {
59+
[`/dashboards/${id}`, `/dashboards/${id}-anything-here`, `/dashboard/${slug}`].forEach((url) => {
6460
cy.visit(url);
6561
cy.wait("@LoadDashboard");
6662
cy.getByTestId(`DashboardId${id}Container`).should("exist");
@@ -72,72 +68,65 @@ describe("Dashboard", () => {
7268
});
7369

7470
context("viewport width is at 800px", () => {
75-
before(function() {
71+
before(function () {
7672
cy.login();
7773
cy.createDashboard("Foo Bar")
7874
.then(({ id }) => {
7975
this.dashboardUrl = `/dashboards/${id}`;
8076
this.dashboardEditUrl = `/dashboards/${id}?edit`;
8177
return cy.addTextbox(id, "Hello World!").then(getWidgetTestId);
8278
})
83-
.then(elTestId => {
79+
.then((elTestId) => {
8480
cy.visit(this.dashboardUrl);
8581
cy.getByTestId(elTestId).as("textboxEl");
8682
});
8783
});
8884

89-
beforeEach(function() {
85+
beforeEach(function () {
9086
cy.login();
9187
cy.visit(this.dashboardUrl);
9288
cy.viewport(800 + menuWidth, 800);
9389
});
9490

9591
it("shows widgets with full width", () => {
96-
cy.get("@textboxEl").should($el => {
92+
cy.get("@textboxEl").should(($el) => {
9793
expect($el.width()).to.eq(770);
9894
});
9995

10096
cy.viewport(801 + menuWidth, 800);
101-
cy.get("@textboxEl").should($el => {
102-
expect($el.width()).to.eq(378);
97+
cy.get("@textboxEl").should(($el) => {
98+
expect($el.width()).to.eq(182);
10399
});
104100
});
105101

106102
it("hides edit option", () => {
107-
cy.getByTestId("DashboardMoreButton")
108-
.click()
109-
.should("be.visible");
103+
cy.getByTestId("DashboardMoreButton").click().should("be.visible");
110104

111-
cy.getByTestId("DashboardMoreButtonMenu")
112-
.contains("Edit")
113-
.as("editButton")
114-
.should("not.be.visible");
105+
cy.getByTestId("DashboardMoreButtonMenu").contains("Edit").as("editButton").should("not.be.visible");
115106

116107
cy.viewport(801 + menuWidth, 800);
117108
cy.get("@editButton").should("be.visible");
118109
});
119110

120-
it("disables edit mode", function() {
111+
it("disables edit mode", function () {
121112
cy.viewport(801 + menuWidth, 800);
122113
cy.visit(this.dashboardEditUrl);
123-
cy.contains("button", "Done Editing")
124-
.as("saveButton")
125-
.should("exist");
114+
cy.contains("button", "Done Editing").as("saveButton").should("exist");
126115

127116
cy.viewport(800 + menuWidth, 800);
128117
cy.contains("button", "Done Editing").should("not.exist");
129118
});
130119
});
131120

132121
context("viewport width is at 767px", () => {
133-
before(function() {
122+
before(function () {
134123
cy.login();
135124
cy.createDashboard("Foo Bar").then(({ id }) => {
136125
this.dashboardUrl = `/dashboards/${id}`;
137126
});
138127
});
139128

140-
beforeEach(function() {
129+
beforeEach(function () {
141130
cy.visit(this.dashboardUrl);
142131
cy.viewport(767, 800);
143132
});

client/cypress/integration/dashboard/grid_compliant_widgets_spec.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import { getWidgetTestId, editDashboard, resizeBy } from "../../support/dashboar
55
const menuWidth = 80;
66

77
describe("Grid compliant widgets", () => {
8-
beforeEach(function() {
8+
beforeEach(function () {
99
cy.login();
1010
cy.viewport(1215 + menuWidth, 800);
1111
cy.createDashboard("Foo Bar")
1212
.then(({ id }) => {
1313
this.dashboardUrl = `/dashboards/${id}`;
1414
return cy.addTextbox(id, "Hello World!").then(getWidgetTestId);
1515
})
16-
.then(elTestId => {
16+
.then((elTestId) => {
1717
cy.visit(this.dashboardUrl);
1818
cy.getByTestId(elTestId).as("textboxEl");
1919
});
@@ -27,7 +27,7 @@ describe("Grid compliant widgets", () => {
2727

2828
it("stays put when dragged under snap threshold", () => {
2929
cy.get("@textboxEl")
30-
.dragBy(90)
30+
.dragBy(30)
3131
.invoke("offset")
3232
.should("have.property", "left", 15 + menuWidth); // no change, 15 -> 15
3333
});
@@ -36,14 +36,14 @@ describe("Grid compliant widgets", () => {
3636
cy.get("@textboxEl")
3737
.dragBy(110)
3838
.invoke("offset")
39-
.should("have.property", "left", 215 + menuWidth); // moved by 200, 15 -> 215
39+
.should("have.property", "left", 115 + menuWidth); // moved by 100, 15 -> 115
4040
});
4141

4242
it("moves two columns when dragged over snap threshold", () => {
4343
cy.get("@textboxEl")
44-
.dragBy(330)
44+
.dragBy(200)
4545
.invoke("offset")
46-
.should("have.property", "left", 415 + menuWidth); // moved by 400, 15 -> 415
46+
.should("have.property", "left", 215 + menuWidth); // moved by 200, 15 -> 215
4747
});
4848
});
4949

@@ -52,7 +52,7 @@ describe("Grid compliant widgets", () => {
5252
cy.route("POST", "**/api/widgets/*").as("WidgetSave");
5353

5454
editDashboard();
55-
cy.get("@textboxEl").dragBy(330);
55+
cy.get("@textboxEl").dragBy(100);
5656
cy.wait("@WidgetSave");
5757
});
5858
});
@@ -64,24 +64,24 @@ describe("Grid compliant widgets", () => {
6464
});
6565

6666
it("stays put when dragged under snap threshold", () => {
67-
resizeBy(cy.get("@textboxEl"), 90)
67+
resizeBy(cy.get("@textboxEl"), 30)
6868
.then(() => cy.get("@textboxEl"))
6969
.invoke("width")
70-
.should("eq", 585); // no change, 585 -> 585
70+
.should("eq", 285); // no change, 285 -> 285
7171
});
7272

7373
it("moves one column when dragged over snap threshold", () => {
7474
resizeBy(cy.get("@textboxEl"), 110)
7575
.then(() => cy.get("@textboxEl"))
7676
.invoke("width")
77-
.should("eq", 785); // resized by 200, 585 -> 785
77+
.should("eq", 385); // resized by 200, 185 -> 385
7878
});
7979

8080
it("moves two columns when dragged over snap threshold", () => {
8181
resizeBy(cy.get("@textboxEl"), 400)
8282
.then(() => cy.get("@textboxEl"))
8383
.invoke("width")
84-
.should("eq", 985); // resized by 400, 585 -> 985
84+
.should("eq", 685); // resized by 400, 285 -> 685
8585
});
8686
});
8787

@@ -101,16 +101,16 @@ describe("Grid compliant widgets", () => {
101101
resizeBy(cy.get("@textboxEl"), 0, 30)
102102
.then(() => cy.get("@textboxEl"))
103103
.invoke("height")
104-
.should("eq", 185); // resized by 50, , 135 -> 185
104+
.should("eq", 185);
105105
});
106106

107107
it("shrinks to minimum", () => {
108108
cy.get("@textboxEl")
109-
.then($el => resizeBy(cy.get("@textboxEl"), -$el.width(), -$el.height())) // resize to 0,0
109+
.then(($el) => resizeBy(cy.get("@textboxEl"), -$el.width(), -$el.height())) // resize to 0,0
110110
.then(() => cy.get("@textboxEl"))
111-
.should($el => {
111+
.should(($el) => {
112112
expect($el.width()).to.eq(185); // min textbox width
113-
expect($el.height()).to.eq(35); // min textbox height
113+
expect($el.height()).to.eq(85); // min textbox height
114114
});
115115
});
116116
});

client/cypress/integration/dashboard/textbox_spec.js

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { getWidgetTestId, editDashboard } from "../../support/dashboard";
44

55
describe("Textbox", () => {
6-
beforeEach(function() {
6+
beforeEach(function () {
77
cy.login();
88
cy.createDashboard("Foo Bar").then(({ id }) => {
99
this.dashboardId = id;
@@ -12,12 +12,10 @@ describe("Textbox", () => {
1212
});
1313

1414
const confirmDeletionInModal = () => {
15-
cy.get(".ant-modal .ant-btn")
16-
.contains("Delete")
17-
.click({ force: true });
15+
cy.get(".ant-modal .ant-btn").contains("Delete").click({ force: true });
1816
};
1917

20-
it("adds textbox", function() {
18+
it("adds textbox", function () {
2119
cy.visit(this.dashboardUrl);
2220
editDashboard();
2321
cy.getByTestId("AddTextboxButton").click();
@@ -29,10 +27,10 @@ describe("Textbox", () => {
2927
cy.get(".widget-text").should("exist");
3028
});
3129

32-
it("removes textbox by X button", function() {
30+
it("removes textbox by X button", function () {
3331
cy.addTextbox(this.dashboardId, "Hello World!")
3432
.then(getWidgetTestId)
35-
.then(elTestId => {
33+
.then((elTestId) => {
3634
cy.visit(this.dashboardUrl);
3735
editDashboard();
3836

@@ -45,32 +43,30 @@ describe("Textbox", () => {
4543
});
4644
});
4745

48-
it("removes textbox by menu", function() {
46+
it("removes textbox by menu", function () {
4947
cy.addTextbox(this.dashboardId, "Hello World!")
5048
.then(getWidgetTestId)
51-
.then(elTestId => {
49+
.then((elTestId) => {
5250
cy.visit(this.dashboardUrl);
5351
cy.getByTestId(elTestId).within(() => {
5452
cy.getByTestId("WidgetDropdownButton").click();
5553
});
56-
cy.getByTestId("WidgetDropdownButtonMenu")
57-
.contains("Remove from Dashboard")
58-
.click();
54+
cy.getByTestId("WidgetDropdownButtonMenu").contains("Remove from Dashboard").click();
5955

6056
confirmDeletionInModal();
6157
cy.getByTestId(elTestId).should("not.exist");
6258
});
6359
});
6460

65-
it("allows opening menu after removal", function() {
61+
it("allows opening menu after removal", function () {
6662
let elTestId1;
6763
cy.addTextbox(this.dashboardId, "txb 1")
6864
.then(getWidgetTestId)
69-
.then(elTestId => {
65+
.then((elTestId) => {
7066
elTestId1 = elTestId;
7167
return cy.addTextbox(this.dashboardId, "txb 2").then(getWidgetTestId);
7268
})
73-
.then(elTestId2 => {
69+
.then((elTestId2) => {
7470
cy.visit(this.dashboardUrl);
7571
editDashboard();
7672

@@ -97,36 +93,32 @@ describe("Textbox", () => {
9793
});
9894
});
9995

100-
it("edits textbox", function() {
96+
it("edits textbox", function () {
10197
cy.addTextbox(this.dashboardId, "Hello World!")
10298
.then(getWidgetTestId)
103-
.then(elTestId => {
99+
.then((elTestId) => {
104100
cy.visit(this.dashboardUrl);
105101
cy.getByTestId(elTestId)
106102
.as("textboxEl")
107103
.within(() => {
108104
cy.getByTestId("WidgetDropdownButton").click();
109105
});
110106

111-
cy.getByTestId("WidgetDropdownButtonMenu")
112-
.contains("Edit")
113-
.click();
107+
cy.getByTestId("WidgetDropdownButtonMenu").contains("Edit").click();
114108

115109
const newContent = "[edited]";
116110
cy.getByTestId("TextboxDialog")
117111
.should("exist")
118112
.within(() => {
119-
cy.get("textarea")
120-
.clear()
121-
.type(newContent);
113+
cy.get("textarea").clear().type(newContent);
122114
cy.contains("button", "Save").click();
123115
});
124116

125117
cy.get("@textboxEl").should("contain", newContent);
126118
});
127119
});
128120

129-
it("renders textbox according to position configuration", function() {
121+
it("renders textbox according to position configuration", function () {
130122
const id = this.dashboardId;
131123
const txb1Pos = { col: 0, row: 0, sizeX: 3, sizeY: 2 };
132124
const txb2Pos = { col: 1, row: 1, sizeX: 3, sizeY: 4 };
@@ -135,15 +127,15 @@ describe("Textbox", () => {
135127
cy.addTextbox(id, "x", { position: txb1Pos })
136128
.then(() => cy.addTextbox(id, "x", { position: txb2Pos }))
137129
.then(getWidgetTestId)
138-
.then(elTestId => {
130+
.then((elTestId) => {
139131
cy.visit(this.dashboardUrl);
140132
return cy.getByTestId(elTestId);
141133
})
142-
.should($el => {
134+
.should(($el) => {
143135
const { top, left } = $el.offset();
144136
expect(top).to.be.oneOf([162, 162.015625]);
145-
expect(left).to.eq(282);
146-
expect($el.width()).to.eq(545);
137+
expect(left).to.eq(188);
138+
expect($el.width()).to.eq(265);
147139
expect($el.height()).to.eq(185);
148140
});
149141
});

0 commit comments

Comments
 (0)