+
{
diff --git a/tests/e2e/invoicing-period.smoke.spec.js b/tests/e2e/invoicing-period.smoke.spec.js
index ff776552..60c4650f 100644
--- a/tests/e2e/invoicing-period.smoke.spec.js
+++ b/tests/e2e/invoicing-period.smoke.spec.js
@@ -1288,6 +1288,27 @@ test.describe("Invoicing period tab", () => {
await expect(page.getByTestId("date-period-start")).toHaveCount(0);
expect(selectedPeriodRequests).toHaveLength(0);
+ const mainRegion = page.getByTestId("invoicing-period-layout-main");
+ const navigationRegion = page.getByTestId("invoicing-period-layout-navigation");
+ const mainBox = await getBoundingBox(mainRegion, "period main region");
+ const navigationBox = await getBoundingBox(navigationRegion, "period navigation region");
+ const monthSelectorBox = await getBoundingBox(monthSelector, "inline month selector");
+ const viewportWidth = page.viewportSize()?.width ?? 0;
+
+ expectBoxInside(monthSelectorBox, mainBox, "inline month selector");
+ expect(monthSelectorBox.width).toBeGreaterThanOrEqual(Math.min(320, mainBox.width - 2));
+ expect(monthSelectorBox.width).toBeLessThanOrEqual(514);
+ if (viewportWidth >= 1024) {
+ expect(navigationBox.x).toBeGreaterThanOrEqual(mainBox.x + mainBox.width + 8);
+ expect(navigationBox.width / (mainBox.width + navigationBox.width)).toBeGreaterThanOrEqual(0.2);
+ expect(navigationBox.width / (mainBox.width + navigationBox.width)).toBeLessThanOrEqual(0.4);
+ } else {
+ expect(navigationBox.y + navigationBox.height).toBeLessThanOrEqual(mainBox.y + 1);
+ }
+ await expect
+ .poll(() => page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth))
+ .toBeLessThanOrEqual(2);
+
const julyOption = monthSelector.locator(".datepicker-months .datepicker-cell").filter({ hasText: /jul/i });
await expect(julyOption).toHaveCount(1);
await julyOption.click();
@@ -1366,7 +1387,7 @@ test.describe("Invoicing period tab", () => {
const tabletQueueBox = await page.locator(".period-review-queue").boundingBox();
expect(tabletDetailBox).not.toBeNull();
expect(tabletQueueBox).not.toBeNull();
- expect(tabletDetailBox.x).toBeGreaterThan(tabletQueueBox.x);
+ expect(tabletDetailBox.y).toBeLessThan(tabletQueueBox.y);
await expect
.poll(() => page.evaluate(() => document.documentElement.scrollWidth <= document.documentElement.clientWidth))
.toBe(true);
@@ -2294,12 +2315,14 @@ test.describe("Invoicing period tab", () => {
const tableContainer = document.querySelector(
'[data-testid="department-75-combined-distribution-table-container"]'
);
- const navigation = document.querySelector('[data-testid="invoicing-period-view-selectors"]');
- if (!tableContainer || !navigation) {
+ const content = document.querySelector('[data-testid="invoicing-period-layout-main"]');
+ const navigation = document.querySelector('[data-testid="invoicing-period-layout-navigation"]');
+ if (!tableContainer || !content || !navigation) {
return false;
}
const tableContainerRect = tableContainer.getBoundingClientRect();
+ const contentRect = content.getBoundingClientRect();
const navigationRect = navigation.getBoundingClientRect();
const selectorRects = Array.from(navigation.querySelectorAll(".is-selector-view")).map((selector) =>
selector.getBoundingClientRect()
@@ -2308,7 +2331,9 @@ test.describe("Invoicing period tab", () => {
document.documentElement.scrollWidth - document.documentElement.clientWidth <= 2 &&
navigation.scrollWidth - navigation.clientWidth <= 2 &&
tableContainer.scrollWidth - tableContainer.clientWidth <= 2 &&
- tableContainerRect.top >= navigationRect.bottom - 1 &&
+ tableContainerRect.left >= contentRect.left - 1 &&
+ tableContainerRect.right <= contentRect.right + 1 &&
+ contentRect.right <= navigationRect.left - 8 &&
selectorRects.every(
(rect) =>
rect.left >= navigationRect.left - 1 &&
diff --git a/tests/unit/superuser-invoices-view.spec.js b/tests/unit/superuser-invoices-view.spec.js
index a13772ad..1bbdb66c 100644
--- a/tests/unit/superuser-invoices-view.spec.js
+++ b/tests/unit/superuser-invoices-view.spec.js
@@ -38,6 +38,13 @@ const periodSource = readFileSync(
join(root, "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/InvoicingBillingPeriod.vue"),
"utf8"
);
+const periodLayoutSource = readFileSync(
+ join(
+ root,
+ "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/displays/layout/InvoicingBillingPeriodLayoutDefault.vue"
+ ),
+ "utf8"
+);
const periodTopSource = readFileSync(
join(root, "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/displays/layout/Top.vue"),
"utf8"
@@ -89,6 +96,10 @@ const periodViewAllSource = readFileSync(
join(root, "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/views/InvoicingBillingPeriodViewAll.vue"),
"utf8"
);
+const periodViewHomeSource = readFileSync(
+ join(root, "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/views/InvoicingBillingPeriodViewHome.vue"),
+ "utf8"
+);
const periodObjectTreeSource = readFileSync(
join(root, "src/views/dashboards/superUserDashboard/InvoicingBillingPeriod/components/InvoicingPeriodObjectTree.vue"),
"utf8"
@@ -409,6 +420,38 @@ describe("Periode tab contract", () => {
expect(periodSource).toContain("");
});
+ it("places period content beside a three-to-one right navigation rail on desktop", () => {
+ expect(periodLayoutSource).toContain('data-testid="invoicing-period-layout-navigation"');
+ expect(periodLayoutSource).toContain('data-testid="invoicing-period-layout-main"');
+ expect(periodLayoutSource).toContain('"content navigation"');
+ expect(periodLayoutSource).toContain("grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);");
+ expect(periodLayoutSource).toContain("@media screen and (min-width: 1024px)");
+ expect(periodLayoutSource).toContain('"navigation"');
+ expect(periodLayoutSource).toContain('"content"');
+ });
+
+ it("stacks grouped selectors in the desktop rail and keeps compact navigation responsive", () => {
+ expect(periodRightSource).toContain("grid-template-columns: minmax(0, 1fr);");
+ expect(periodRightSource).toContain("@media screen and (min-width: 601px) and (max-width: 1023px)");
+ expect(periodRightSource).toContain("grid-template-columns: repeat(2, minmax(0, 1fr));");
+ expect(periodRightSource).toContain("@media screen and (max-width: 600px)");
+ expect(periodRightSource).toContain("flex: 0 0 min(82vw, 320px);");
+ });
+
+ it("adapts the review workspace to the main region width created by the right rail", () => {
+ expect(periodViewAllSource).toContain('class="invoicing-period-view-all"');
+ expect(periodViewAllSource).toContain("container-type: inline-size;");
+ expect(periodViewAllSource).toContain("grid-template-columns: minmax(330px, 0.8fr) minmax(0, 1.6fr);");
+ expect(periodViewAllSource).toContain("@container (max-width: 1024px)");
+ });
+
+ it("sizes the inline month selector to the available content width with a readable cap", () => {
+ expect(periodViewHomeSource).toContain('class="invoicing-period-month-entry__selector"');
+ expect(periodViewHomeSource).toContain("max-width: 32rem;");
+ expect(periodViewHomeSource).toContain(":deep(.datepicker-months)");
+ expect(periodViewHomeSource).toContain("min-height: 3rem;");
+ });
+
it("keeps top selector and left dynamic view renderer", () => {
expect(periodTopSource).toContain("