Skip to content
Merged
10 changes: 4 additions & 6 deletions QualityControl/public/layout/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ export default class Layout extends BaseViewModel {
const result = await this.model.services.layout.saveLayout(this.item);
if (result.isSuccess()) {
await this.model.services.layout.getLayoutsByUserId(this.model.session.personid);
this._tabIndex = this._tabIndex < this.item.tabs.length ? this._tabIndex : 0;
this.selectTab(this._tabIndex);
this.model.notification.show(`Layout "${this.item.name}" has been saved successfully.`, 'success');
} else {
this.item = this.editOriginalClone;
Expand All @@ -287,9 +289,7 @@ export default class Layout extends BaseViewModel {
this.gridListSize = parseInt(value, 10);
this.cellHeight = 100 / this.gridListSize * 0.95; // %, put some margin at bottom to see below
this.cellWidth = 100 / this.gridListSize; // %
if (this.editEnabled) {
this.gridList.resizeGrid(this.gridListSize);
}
this.gridList.resizeGrid(this.gridListSize);
this.tab.columns = this.gridListSize;
this.tab.objects.forEach((object) => {
if (object.w > this.tab.columns) {
Expand All @@ -306,9 +306,7 @@ export default class Layout extends BaseViewModel {
*/
sortObjectsOfCurrentTab() {
this.gridList.items = this.tab.objects;
if (this.editEnabled) {
this.gridList.resizeGrid(this.gridListSize);
}
this.gridList.resizeGrid(this.gridListSize);
}

/**
Expand Down
79 changes: 73 additions & 6 deletions QualityControl/test/public/pages/layout-show.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@

import { strictEqual, ok, deepStrictEqual } from 'node:assert';
import { delay } from '../../testUtils/delay.js';
import { editedMockedLayout } from '../../setup/seeders/layout-show/json-file-mock.js';
import {
editedManyObjectsMockedLayout,
editedMockedLayout,
} from '../../setup/seeders/layout-show/json-file-mock.js';
import { getElementCenter } from '../../testUtils/dragAndDrop.js';

/**
Expand Down Expand Up @@ -187,7 +190,7 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
const leftStyle = await page.evaluate(() => document.querySelector('#subcanvas .dropdown-menu').style.left);

strictEqual(leftStyle, '0.1em');
}
},
);

await testParent.test('should have second tab to be empty (according to demo data)', { timeout }, async () => {
Expand Down Expand Up @@ -349,7 +352,7 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
elements.map((element) => element.textContent.trim()));

strictEqual(tabNames[1], originalTabNames[0]);
}
},
);

await testParent.test(
Expand Down Expand Up @@ -446,9 +449,69 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
},
);

await testParent.test(
'should display all objects even when the JSON has out of bound entries',
{ timeout: 15000 },
async () => {
const EXPECTED_LAYOUT_OBJECT_COUNT = editedManyObjectsMockedLayout.tabs[0].objects.length;

/**
* Counts the number of visible child elements within #subcanvas.
* Visibility is defined as being within the viewport.
* @returns {number} The amount of visible rendered objects
*/
const getVisibleObjectCount = async () =>
await page.evaluate(() => {
const container = document.querySelector('#subcanvas');
if (!container) {
return 0;
}

// Count elements that intersect with the viewport
return Array.from(container.children).filter((child) => {
const rect = child.getBoundingClientRect();
return rect.bottom >= 0 && rect.top >= 0 && rect.left >= 0 && rect.right <= window.innerWidth;
}).length;
});

// Ensure we are on the main tab
await page.locator('#tab-0').click();
await delay(100);

const pencilButtonPath = '.btn-group > div > button';
await page.locator(pencilButtonPath).click();

const editViaJSONButtonPath = '#editByJson';
await page.locator(editViaJSONButtonPath).click();

const textareaPath = '#layout-json-editor';
const mockedJSON = JSON.stringify(editedManyObjectsMockedLayout);
await page.locator(textareaPath).fill(mockedJSON);

const updateButtonPath = '#updateLayoutButton';
await page.locator(updateButtonPath).click();
await delay(100);

strictEqual(
await getVisibleObjectCount(),
EXPECTED_LAYOUT_OBJECT_COUNT,
`Expected ${EXPECTED_LAYOUT_OBJECT_COUNT} rendered objects after JSON update`,
);

await page.reload({ waitUntil: 'networkidle0' });
await delay(100);

strictEqual(
await getVisibleObjectCount(),
EXPECTED_LAYOUT_OBJECT_COUNT,
`Expected ${EXPECTED_LAYOUT_OBJECT_COUNT} rendered objects after page reload`,
);
},
);

await testParent.test(
'should update layout when clicking "Update layout"',
{ timeout },
{ timeout: 10000 },
async () => {
const pencilButtonPath = '.btn-group > div > button';
await page.locator(pencilButtonPath).click();
Expand All @@ -474,16 +537,20 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
);

await testParent.test('should change tab after set tabInterval', { timeout: 15000 }, async () => {
// Ensure we are on the 'a' tab
await page.locator('#tab-1').click();
await delay(100);

const location = await page.evaluate(() => window.location);
strictEqual(location.search, `?page=layoutShow&layoutId=${LAYOUT_ID}&tab=a`);
await delay(11000);
await delay(11111);
const location2 = await page.evaluate(() => window.location);
strictEqual(location2.search, `?page=layoutShow&layoutId=${LAYOUT_ID}&tab=test`);
});

await testParent.test(
'should update layout name in sidebar when name is changed and saved via JSON editor',
{ timeout },
{ timeout: 10000 },
async () => {
const originalSidebarName = await page.evaluate(() => {
const sidebarLayoutLink = document.querySelector('nav a.menu-item.w-wrapped.selected span:nth-child(2)');
Expand Down
55 changes: 55 additions & 0 deletions QualityControl/test/setup/seeders/layout-show/json-file-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,58 @@ export const editedMockedLayout = {
displayTimestamp: false,
autoTabChange: 11,
};

export const editedManyObjectsMockedLayout = {
name: 'a-test',
tabs: [
{
name: 'main',
objects: [
{
x: 0,
y: 0,
h: 1,
w: 1,
name: 'qc/test/object/1',
options: [],
ignoreDefaults: false,
},
{
x: 1,
y: 0,
h: 1,
w: 1,
name: 'qc/test/object/1',
options: [],
ignoreDefaults: false,
},
{
x: 2,
y: 0,
h: 1,
w: 1,
name: 'qc/test/object/1',
options: [],
ignoreDefaults: false,
},
{
x: 0,
y: 1,
h: 1,
w: 1,
name: 'qc/test/object/1',
options: [],
ignoreDefaults: false,
},
],
columns: 1,
},
{
name: 'a',
objects: [],
columns: 1,
},
],
displayTimestamp: false,
autoTabChange: 11,
};