diff --git a/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-components.test.ts b/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-components.test.ts index 0ca4996..7e077d0 100644 --- a/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-components.test.ts +++ b/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-components.test.ts @@ -194,7 +194,7 @@ describe("analytics presentation components", () => { it("keeps previous breakdown, event, and flag rows visible while filters refresh", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "Country"); + element.cards = dashboardCards("unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "Country"); element.breakdowns = { Country: loadingState(successState({ dimension: "Country", rows: [{ value: "DK", visitors: 12, pageViews: 18 }] })), }; @@ -251,7 +251,7 @@ describe("analytics presentation components", () => { it("emits audience changes from the breakdown tabs", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable").filter((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); + element.cards = dashboardCards("unavailable").filter((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); element.audienceDimension = "DeviceType"; element.breakdowns = { DeviceType: successState({ dimension: "DeviceType", rows: [] }), @@ -276,7 +276,7 @@ describe("analytics presentation components", () => { it("keeps audience cards as percentages of the selected metric", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable").filter((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); + element.cards = dashboardCards("unavailable").filter((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); element.audienceDimension = "DeviceType"; element.metric = "visitors"; element.breakdowns = { @@ -306,7 +306,7 @@ describe("analytics presentation components", () => { it("keeps standard cards focused on the selected metric", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "RequestPath"); + element.cards = dashboardCards("unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "RequestPath"); element.metric = "pageViews"; element.breakdowns = { RequestPath: successState({ dimension: "RequestPath", rows: [{ value: "/", visitors: 8_525, pageViews: 15_119 }] }), @@ -397,27 +397,28 @@ describe("analytics presentation components", () => { expect(icons.map((icon) => icon.getAttribute("name"))).toEqual(["icon-desktop", "icon-mobile", "icon-ipad"]); }); - it("keeps document traffic breakdowns ahead of optional reports", async () => { + it("keeps document pages and traffic breakdowns ahead of optional reports", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(true, "unavailable"); + element.cards = dashboardCards("unavailable"); element.events = successState({ rows: [{ eventName: "Signup", visitors: 12, count: 18 }] }); document.body.append(element); await element.updateComplete; const cards = [...element.shadowRoot?.querySelectorAll("uui-box") ?? []]; - expect(cards.slice(0, 4).map((card) => card.querySelector("web-analytics-breakdown-table")?.headline)).toEqual([ + expect(cards.slice(0, 5).map((card) => card.querySelector("web-analytics-breakdown-table")?.headline)).toEqual([ + "Pages", "Referrers", "Countries", "Devices", "Operating systems", ]); - expect(cards[4]?.querySelector("web-analytics-event-table")).not.toBeNull(); - expect(cards[5]?.querySelector("web-analytics-flag-table")).not.toBeNull(); + expect(cards[5]?.querySelector("web-analytics-event-table")).not.toBeNull(); + expect(cards[6]?.querySelector("web-analytics-flag-table")).not.toBeNull(); }); it("keeps View all actions low priority while retaining emphasis for Retry", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "Country"); + element.cards = dashboardCards("unavailable").filter((card) => card.kind === "breakdown" && card.dimension === "Country"); element.breakdowns = { Country: successState({ dimension: "Country", rows: [{ value: "DK", visitors: 12, pageViews: 18 }] }), }; @@ -448,7 +449,7 @@ describe("analytics presentation components", () => { it("groups Events and Flags as optional reports in the overview", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unavailable"); + element.cards = dashboardCards("unavailable"); element.events = successState({ rows: [] }); document.body.append(element); await element.updateComplete; @@ -463,7 +464,7 @@ describe("analytics presentation components", () => { it("keeps a lone optional report in one feature-grid track", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(true, "unavailable"); + element.cards = dashboardCards("unavailable"); element.supportsEvents = false; element.supportsFlags = true; element.events = successState({ rows: [] }); @@ -481,7 +482,7 @@ describe("analytics presentation components", () => { it("merges valid UTM reports into the referrers card with five parameter tabs", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "available"); + element.cards = dashboardCards("available"); element.breakdowns = { ReferrerHostname: successState({ dimension: "ReferrerHostname", rows: [{ value: "google.com", visitors: 8, pageViews: 10 }] }), UtmSource: successState({ dimension: "UtmSource", rows: [{ value: "newsletter", visitors: 5, pageViews: 6 }] }), @@ -524,7 +525,7 @@ describe("analytics presentation components", () => { it("keeps the UTM tab hidden until a UTM report is valid", async () => { const element = document.createElement("web-analytics-breakdown-grid") as WebAnalyticsBreakdownGridElement; - element.cards = dashboardCards(false, "unknown"); + element.cards = dashboardCards("unknown"); element.breakdowns = { ReferrerHostname: successState({ dimension: "ReferrerHostname", rows: [] }), }; diff --git a/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-dashboard.controller.ts b/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-dashboard.controller.ts index 9640759..9fea6fc 100644 --- a/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-dashboard.controller.ts +++ b/src/TheBuilder.WebAnalytics/Client/src/analytics/analytics-dashboard.controller.ts @@ -555,7 +555,6 @@ export class AnalyticsDashboardController { const capabilities = this.#capabilities(); const referrerDimension = capabilities.dimensions.includes("ReferrerHostname") ? "ReferrerHostname" : "Referrer"; const plan = dashboardReportPlan( - Boolean(this.#documentId), utmCapability, this.state.acquisitionView, this.state.utmDimension, diff --git a/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.test.ts b/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.test.ts index c3a4f70..7f5fab7 100644 --- a/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.test.ts +++ b/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.test.ts @@ -2,9 +2,8 @@ import { describe, expect, it } from "vitest"; import { dashboardCards, dashboardReportPlan, selectedCardDimension } from "./dashboard-cards.js"; describe("dashboardCards", () => { - it("models pages globally and omits them for a document", () => { - expect(reportPlan({ documentScoped: false }).dimensions).toContain("RequestPath"); - expect(reportPlan({ documentScoped: true }).dimensions).not.toContain("RequestPath"); + it("models pages", () => { + expect(reportPlan().dimensions).toContain("RequestPath"); }); it("models audience and UTM dimensions as tabbed cards without eagerly loading hidden UTM tabs", () => { @@ -31,26 +30,24 @@ describe("dashboardCards", () => { it("shows the UTM card only after capability is known to be available", () => { for (const capability of ["unknown", "unavailable"] as const) { - expect(dashboardCards(false, capability).some((card) => card.kind === "tabbed-breakdown" && card.id === "utm")).toBe(false); + expect(dashboardCards(capability).some((card) => card.kind === "tabbed-breakdown" && card.id === "utm")).toBe(false); } }); it("selects the active option from a tabbed card", () => { - const audience = dashboardCards(false, "available").find((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); + const audience = dashboardCards("available").find((card) => card.kind === "tabbed-breakdown" && card.id === "audience"); expect(audience && selectedCardDimension(audience, "BrowserName", "UtmSource").dimension).toBe("BrowserName"); }); }); type ReportPlanOverrides = { - documentScoped?: Parameters[0]; - utmCapability?: Parameters[1]; - acquisitionView?: Parameters[2]; - utmDimension?: Parameters[3]; + utmCapability?: Parameters[0]; + acquisitionView?: Parameters[1]; + utmDimension?: Parameters[2]; }; function reportPlan(overrides: ReportPlanOverrides = {}) { return dashboardReportPlan( - overrides.documentScoped ?? false, overrides.utmCapability ?? "available", overrides.acquisitionView ?? "referrers", overrides.utmDimension ?? "UtmSource", diff --git a/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.ts b/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.ts index 54488c1..d1aaa72 100644 --- a/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.ts +++ b/src/TheBuilder.WebAnalytics/Client/src/analytics/dashboard-cards.ts @@ -71,12 +71,11 @@ const UTM_CARD: DashboardCard = { }; export function dashboardCards( - documentScoped: boolean, utmCapability: UtmCapability, referrerDimension: "ReferrerHostname" | "Referrer" = "ReferrerHostname", ): ReadonlyArray { const cards: DashboardCard[] = [ - ...(documentScoped ? [] : [{ kind: "breakdown" as const, dimension: "RequestPath" as const, headline: "Pages", span: "wide" as const }]), + { kind: "breakdown", dimension: "RequestPath", headline: "Pages", span: "wide" }, { kind: "breakdown", ...referrerDimensionOption(referrerDimension), span: "wide" }, ...SHARED_CARDS, ]; @@ -85,13 +84,12 @@ export function dashboardCards( } export function dashboardReportPlan( - documentScoped: boolean, utmCapability: UtmCapability, acquisitionView: AcquisitionView, utmDimension: UtmDimension, referrerDimension: "ReferrerHostname" | "Referrer" = "ReferrerHostname", ): DashboardReportPlan { - const cards = dashboardCards(documentScoped, utmCapability, referrerDimension); + const cards = dashboardCards(utmCapability, referrerDimension); const dimensions = cards.flatMap((card) => card.kind === "breakdown" ? [card.dimension] : card.reportLoading === "eager" ? card.options.map(({ dimension }) => dimension) : []);