Skip to content

feat(dashboards): show all sections on overview tab#725

Open
mrautela365 wants to merge 23 commits into
mainfrom
feat/LFXV2-1644-overview-all-sections
Open

feat(dashboards): show all sections on overview tab#725
mrautela365 wants to merge 23 commits into
mainfrom
feat/LFXV2-1644-overview-all-sections

Conversation

@mrautela365
Copy link
Copy Markdown
Contributor

Summary

  • Embed all marketing impact sections into the Overview tab so it serves as the full dashboard summary
  • Order: KPI cards → Attribution → Performance Marketing → Email → Web Activity → Social Accounts → Social Listening
  • Individual tabs still show the focused detail view when selected
  • Each embedded section fetches its own data independently (same foundationSlug input)

Test plan

  • Navigate to /foundation/marketing-impact?project=tlf → Overview tab
  • Verify all sections appear stacked: KPI cards, attribution, performance marketing, email, web activity, social accounts, social listening
  • Click individual tabs (Attribution, Performance Marketing, etc.) and verify they show the focused view
  • Switch back to Overview and verify all sections are still visible
  • Verify loading states work independently per section

LFXV2-1644

🤖 Generated with Claude Code

@mrautela365 mrautela365 requested a review from a team as a code owner May 17, 2026 21:13
Copilot AI review requested due to automatic review settings May 17, 2026 21:13
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds six marketing-impact dashboard tabs (attribution, email, performance-marketing, web-activity, social-accounts, social-listening), shared view-models/constants and trend helpers, refactors overview KPI aggregation/formatting, updates KPI-card test IDs/section support, and wires tabs into the marketing-impact shell.

Changes

Marketing Impact Dashboard Extension

Layer / File(s) Summary
Shared types, constants, and trend utilities
packages/shared/src/interfaces/marketing-impact.interface.ts, packages/shared/src/constants/marketing-impact.constants.ts, packages/shared/src/utils/marketing-impact.utils.ts
Defines view-model types (AttributionChannelRow, EmailTypeRow, PaidProjectRow, SocialAccountRow, SentimentBar, WebActivityDomainRow), renames AttributionDataOverviewKpiData, makes PerformanceSummaryKpi.comparisonLine optional, adds ATTRIBUTION_MODEL_OPTIONS and FUNNEL_STAGE_OPTIONS, and implements trendDirection, trendColorClass, and formatChangePct.
Attribution section component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/*
Standalone AttributionSectionComponent with form-backed model selector, fetches attribution data by slug, computes channel rows (revenue/share/sessions) per selected model, formats totals, and renders table with loading/empty states and ARIA/test IDs.
Email tab component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/*
EmailTabComponent fetches email CTR analytics, builds KPI cards (sends/opens/open-rate/CTR with MoM deltas and trend metadata), maps email-type breakdown to rows, and selects top-5 campaigns by sends; includes loading/empty state templates.
Performance marketing tab component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/*
PerformanceMarketingTabComponent with funnel-stage filter pills, fetches social reach data, derives impressions KPI with MoM trend, maps project breakdown to PaidProjectRow[] with performance classification and sorting, and renders conditional table/empty state.
Web activity tab component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/*
WebActivityTabComponent fetches web summary analytics, derives KPI cards (sessions/page-views/pages-per-session) with neutral trends, computes domain rows with session-share and formatted metrics, and renders domain breakdown with loading/empty states.
Social accounts tab component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/*
SocialAccountsTabComponent fetches per-platform social analytics, aggregates KPI totals/averages with MoM trends, derives platform rows sorted by followers, and includes loading/empty state template.
Social listening tab component
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/*
SocialListeningTabComponent fetches brand health, derives KPI cards for mentions with MoM trends, computes sentiment distribution, and caps top projects/mentions lists (up to 5); template includes loading/empty states.
KPI card infrastructure updates
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/*
Adds section input and computed testId to SparklineKpiCardComponent, updates template to use testId() for data-testid, and refactors icon rendering.
Overview tab KPI refactoring and subsections
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/*
Refactors OverviewTabComponent to aggregate OverviewKpiData via concurrent forkJoin, uses shared trend helpers for KPI MoM/YoY fields, removes comparisonLine, adds KPI empty state, and appends the six downstream tab sections below the KPI grid.
Marketing impact shell routing
apps/lfx-one/src/app/modules/dashboards/marketing-impact/marketing-impact.component.*
Registers new tab components in imports, removes selectedTabLabel, and replaces the "coming soon" fallback with explicit component branches for each tab that receive foundationSlug/foundationName.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • linuxfoundation/lfx-self-serve#641: Establishes the initial MarketingImpactComponent shell and tab placeholders that this PR extends with dedicated tab implementations.
  • linuxfoundation/lfx-self-serve#705: Earlier PR refactoring KPI markup and MoM/YoY trend fields that this PR builds upon with shared trend utilities and overview KPI aggregation.

Suggested labels

deploy-preview

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: embedding all sections into the Overview tab as a full dashboard summary.
Description check ✅ Passed The description is well-related to the changeset, detailing the section embedding, order, data-fetching approach, and test plan for the Overview tab enhancement.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/LFXV2-1644-overview-all-sections

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts (1)

24-29: ⚡ Quick win

Remove duplicate attribution-model revenue maps to avoid drift.

revenueKeyMap and revenueKeyByModel contain the same mapping, but only one is used. Keeping both invites inconsistent updates later.

♻️ Proposed cleanup
 export class AttributionSectionComponent {
-  private static readonly revenueKeyMap: Record<AttributionModel, 'linearRevenue' | 'firstTouchRevenue' | 'lastTouchRevenue' | 'timeDecayRevenue'> = {
-    linear: 'linearRevenue',
-    firstTouch: 'firstTouchRevenue',
-    lastTouch: 'lastTouchRevenue',
-    timeDecay: 'timeDecayRevenue',
-  };
-
   // === Services ===
   private readonly analyticsService = inject(AnalyticsService);
   private readonly fb = inject(FormBuilder);

Also applies to: 47-52

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts`
around lines 24 - 29, There are two identical maps defined (revenueKeyMap and
revenueKeyByModel) which risks divergence; remove the duplicate and keep a
single source of truth (either revenueKeyMap or revenueKeyByModel), update all
references in AttributionSectionComponent to use the remaining symbol (e.g.,
revenueKeyMap) and delete the other definition, and run/verify compilation and
unit tests to ensure no remaining references to the removed name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts`:
- Around line 165-173: The filter callback in
performance-marketing-tab.component.ts allows rows with empty funnelStage to
pass through for specific funnel filters; update the predicate in the
.filter((p) => { ... }) used in the PerformanceMarketingTab component so that
when funnel !== 'all' you explicitly reject missing or unknown stages (check
p.funnelStage?.toLowerCase() === '' or 'unknown' and return false), then
continue to check funnel === 'tofu' / 'mofu' / 'bofu' using
stage.startsWith('tofu') or exact matches; keep funnel === 'all' returning true.

In
`@apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.ts`:
- Around line 41-53: The toSignal pipeline for slug$ (used in toSignal(...))
currently lets errors from analyticsService.getWebActivitiesSummary(slug) bubble
up; wrap that observable with catchError(() => of(null)) (before finalize(() =>
this.loading.set(false))) so failures return null instead of throwing, and
update imports to include catchError from 'rxjs'; keep the existing
loading.set(true/false) logic around getWebActivitiesSummary to match the
error-handling pattern used in social-accounts-tab and social-listening-tab.

In `@packages/shared/src/utils/marketing-impact.utils.ts`:
- Around line 36-56: The current guards in trendDirection, trendColorClass, and
formatChangePct only check for null/NaN and therefore allow Infinity/-Infinity
to pass through; update each function to treat non-finite numbers as invalid by
using Number.isFinite(pct) (or an equivalent isFinite check) in the initial
condition (e.g., replace the Number.isNaN(pct) check with !Number.isFinite(pct))
so Infinity values return the neutral color/trend and formatChangePct returns
null instead of producing "Infinity%".

---

Nitpick comments:
In
`@apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts`:
- Around line 24-29: There are two identical maps defined (revenueKeyMap and
revenueKeyByModel) which risks divergence; remove the duplicate and keep a
single source of truth (either revenueKeyMap or revenueKeyByModel), update all
references in AttributionSectionComponent to use the remaining symbol (e.g.,
revenueKeyMap) and delete the other definition, and run/verify compilation and
unit tests to ensure no remaining references to the removed name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0a685349-47fe-43aa-b742-ab8f2f7b2dbb

📥 Commits

Reviewing files that changed from the base of the PR and between 3354ca1 and da888fa.

📒 Files selected for processing (25)
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.scss
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.scss
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.scss
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.scss
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.scss
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/sparkline-kpi-card.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/marketing-impact.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/marketing-impact.component.ts
  • packages/shared/src/constants/marketing-impact.constants.ts
  • packages/shared/src/interfaces/marketing-impact.interface.ts
  • packages/shared/src/utils/marketing-impact.utils.ts

Comment thread packages/shared/src/utils/marketing-impact.utils.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Marketing Impact dashboard so the Overview tab becomes a stacked summary of all marketing sections while preserving individual focused tabs.

Changes:

  • Adds dedicated section/tab components for attribution, performance marketing, email, web activity, social accounts, and social listening.
  • Embeds all sections into the Overview tab and routes individual tab selections to the matching component.
  • Adds shared view-model types, constants, and trend formatting helpers for the new marketing-impact UI.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/shared/src/utils/marketing-impact.utils.ts Adds shared trend direction/color/percentage formatting helpers.
packages/shared/src/interfaces/marketing-impact.interface.ts Adds view-model interfaces and marketing-impact tab/filter types.
packages/shared/src/constants/marketing-impact.constants.ts Adds attribution model and funnel-stage option constants.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/marketing-impact.component.ts Imports new tab/section components for the parent dashboard.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/marketing-impact.component.html Replaces placeholder tabs with real focused section components.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.ts Renames KPI data handling and imports embedded section components.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html Embeds all marketing sections below Overview KPI cards.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts Adds attribution data fetching/model selection and channel row shaping.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.html Adds attribution section UI/table.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.scss Adds component stylesheet header.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts Adds paid campaign KPI and project table logic.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html Adds performance marketing tab UI.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.scss Adds component stylesheet header.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.ts Adds email KPI, email type, and campaign table logic.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.html Adds email marketing tab UI.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.scss Adds component stylesheet header.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.ts Adds web activity KPI and domain row logic.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.html Adds web activity tab UI.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.ts Adds social media KPI and platform row logic.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.html Adds social accounts tab UI.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.scss Adds component stylesheet header.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.ts Adds brand health KPI, sentiment, project, and mention logic.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.html Adds social listening tab UI.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.scss Adds component stylesheet header.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/sparkline-kpi-card.component.html Generalizes KPI card test IDs and icon styling.
Comments suppressed due to low confidence (2)

apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.html:77

  • This visual table lacks table, row, columnheader, and cell semantics, so assistive technologies may read the campaign columns as unrelated text. Use a semantic table or add the same ARIA table roles used by the attribution/performance tables in this PR.
        <div class="flex flex-col gap-0" data-testid="email-campaigns-table">
          <!-- Table header -->
          <div class="flex items-center gap-3 border-b border-gray-200 pb-2">
            <span class="flex-1 text-[11px] font-semibold tracking-wide text-gray-400">CAMPAIGN</span>
            <span class="w-24 text-[11px] font-semibold tracking-wide text-gray-400">TYPE</span>
            <span class="w-20 text-right text-[11px] font-semibold tracking-wide text-gray-400">SENDS</span>
            <span class="w-20 text-right text-[11px] font-semibold tracking-wide text-gray-400">OPENS</span>
            <span class="w-20 text-right text-[11px] font-semibold tracking-wide text-gray-400">OPEN RATE</span>
            <span class="w-16 text-right text-[11px] font-semibold tracking-wide text-gray-400">CTR</span>

apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html:54

  • The embedded sections do not receive the selected month, and a search shows selectedMonth is only used to render labels, not to parameterize any data request. Changing the month picker will therefore leave these newly added Overview sections showing the same data under a different month label; pass the selected month through and include it in the section queries, or make the picker unavailable until month-scoped data is supported.
<lfx-attribution-section [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-attribution-section" />

<lfx-performance-marketing-tab [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-performance-marketing" />

<lfx-email-tab [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-email" />

<lfx-web-activity-tab [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-web-activity" />

<lfx-social-accounts-tab [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-social-accounts" />

<lfx-social-listening-tab [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-social-listening" />

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: cf1a547

Changes Made

  • marketing-impact.utils.ts: Changed Number.isNaN(pct) to !Number.isFinite(pct) in trendDirection, trendColorClass, and formatChangePct to guard against Infinity/-Infinity (per coderabbitai[bot], copilot[bot])
  • web-activity-tab.component.ts: Added catchError(() => of(null)) to the data stream to match error handling pattern in sibling tabs (per coderabbitai[bot], copilot[bot])
  • performance-marketing-tab.component.ts: Fixed funnel stage filter to exclude empty/unknown stages and changed fallthrough to return false (per coderabbitai[bot], copilot[bot])
  • attribution-section.component.ts: Removed duplicate revenueKeyMap static field — only revenueKeyByModel retained (per copilot[bot])
  • email-tab.component.html: Added ARIA role="table", role="row", role="columnheader", role="cell" to both email type and top campaigns tables (per copilot[bot])
  • social-accounts-tab.component.html: Added ARIA table roles to platform breakdown table (per copilot[bot])
  • web-activity-tab.component.html: Added ARIA table roles to domain breakdown table (per copilot[bot])
  • social-listening-tab.component.html: Added ARIA table roles to project mentions table (per copilot[bot])
  • sparkline-kpi-card.component.ts/html: Added section input for unique data-testid prefixes across Overview tab sections (per copilot[bot])
  • All tab HTML files: Wired section input on all <lfx-sparkline-kpi-card> usages

No Code Change Needed

  • overview-tab.component.html:54: E2E coverage for the marketing-impact route is planned as a follow-up once tab content stabilizes
  • marketing-impact.component.html:95: FOCUS filter is an intentional UI placeholder for a planned feature — backend doesn't yet support program-level segmentation

Threads Resolved

11 of 11 review threads addressed and resolved.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/sparkline-kpi-card.component.html`:
- Line 13: Update the badge data-testid to be section-scoped to prevent
collisions by including the section identifier alongside the KPI id; replace the
current [attr.data-testid]="'kpi-card-badge-' + kpi().id" with a compound key
that includes the section id (for example "'kpi-card-badge-' + section().id +
'-' + kpi().id"), referencing the existing kpi() and section() accessors used in
this component so tests can target badges uniquely per section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8be1bbf9-621c-49e0-8d3b-bd880eae2187

📥 Commits

Reviewing files that changed from the base of the PR and between da888fa and cf1a547.

📒 Files selected for processing (12)
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/email-tab/email-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-accounts-tab/social-accounts-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/social-listening-tab/social-listening-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/sparkline-kpi-card.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/sparkline-kpi-card/sparkline-kpi-card.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.ts
  • packages/shared/src/utils/marketing-impact.utils.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html
  • packages/shared/src/utils/marketing-impact.utils.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/web-activity-tab/web-activity-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts

Copilot AI review requested due to automatic review settings May 17, 2026 22:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Comment thread packages/shared/src/utils/marketing-impact.utils.ts
@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed (iteration 3)

Commit: f2267d1

Changes Made

  • email-tab.component.ts: Relabeled CTR card suffix from 'MoM' to 'vs avg' — the backend computes this as current vs 6-month average, not month-over-month (per copilot[bot])
  • overview-tab.component.ts: Same CTR suffix correction (per copilot[bot])
  • marketing-impact.utils.ts: Added Math.abs(pct) < 0.05 threshold to trendDirection, trendColorClass, and formatChangePct to prevent -0.0% with a down arrow for tiny negative values (per copilot[bot])

No Change Needed

  • marketing-impact.component.html:95: Month picker doesn't propagate to tab data because analytics APIs only accept foundationSlug — no date range parameter available yet. Planned iteration when backend adds support. (per copilot[bot])
  • overview-tab.component.html:54: Same API limitation — embedded sections show latest available data regardless of selected month. (per copilot[bot])

Threads Resolved

5 of 5 unresolved threads addressed in this iteration.

Copilot AI review requested due to automatic review settings May 18, 2026 15:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings May 18, 2026 16:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.

@mrautela365 mrautela365 force-pushed the feat/LFXV2-1644-overview-all-sections branch from ce5bf01 to 5de8ffd Compare May 18, 2026 17:29
Copilot AI review requested due to automatic review settings May 18, 2026 17:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Copy link
Copy Markdown
Contributor

@MRashad26 MRashad26 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strict pass against ~/LFX/code-enforcer-agent.md. The architectural shift (Overview tab now embeds all six focused-tab components) introduces a perf/duplication concern in the data layer that's worth surfacing before this lands. The earlier computeMomPct extraction into shared utils is a nice follow-through on the PR #720 review.

mrautela365 added a commit that referenced this pull request May 18, 2026
- overview-tab: remove embedded sub-tab components that
  caused duplicate HTTP requests (per MRashad26)
- overview-tab: remove unused sub-tab component imports
- social-listening: sort merged mentions by date descending
  to prevent positive-mention bias in top-5 list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 18, 2026 18:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.

@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 48d4cdb

Changes Made

  • social-accounts-tab.component.ts: Fixed engagement rate to use impression-weighted average instead of unweighted average, so high-volume platforms contribute proportionally to the headline KPI (per copilot[bot])

No Change Needed

  • marketing-impact.component.html: Tab navigation is by design — each tab renders its own component when selected via selectedTab(), avoiding duplicate HTTP requests and unnecessary DOM rendering (per copilot[bot])

Threads Resolved

2 of 2 unresolved threads addressed in this iteration.

mrautela365 added a commit that referenced this pull request May 18, 2026
- overview-tab: remove embedded sub-tab components that
  caused duplicate HTTP requests (per MRashad26)
- overview-tab: remove unused sub-tab component imports
- social-listening: sort merged mentions by date descending
  to prevent positive-mention bias in top-5 list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 18, 2026 23:30
@mrautela365 mrautela365 force-pushed the feat/LFXV2-1644-overview-all-sections branch from 5aae313 to aecd2e5 Compare May 18, 2026 23:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Align platform breakdown and totals ROAS formatting with
the KPI cards and project rows by appending the x suffix.
Add blank line after import in analytics-data interface.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 19, 2026 03:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

mrautela365 and others added 14 commits May 18, 2026 20:56
Add subtitle to platform performance table noting revenue/ROAS use
linear attribution. Add backend comment documenting the intentional
attribution model split between KPI headlines (first-touch) and
drill-down tables (linear).

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Unify all social reach queries on LAST_TOUCH_REVENUE from the
PAID_SOCIAL_REACH_BY_PROJECT_CHANNEL_MONTH table. This eliminates
the attribution model mismatch between KPI headlines (was
first-touch) and drill-down tables (was linear). ROAS MoM is now
computed from two completed months instead of the pre-computed
ROAS_MOM_PCT column.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Embed all tab components (attribution, performance marketing, email,
web activity, social accounts, social listening) into the overview tab
so users see the full dashboard summary. Individual tabs still show
the focused detail view.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
- Guard non-finite percentages (Infinity/-Infinity) in trend utils
- Add catchError to web-activity-tab data stream
- Fix funnel stage filter to exclude empty/unknown stages
- Add ARIA table roles to email, social-accounts, web-activity,
  social-listening tables
- Add section input to sparkline-kpi-card for unique data-testids
- Remove duplicate revenueKeyMap from attribution-section

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Use testId() + '-badge' instead of 'kpi-card-badge-' + kpi().id so
the badge test selector is unique across sections on the Overview tab.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
- Email CTR changePercentage is computed vs 6-month average, not MoM.
  Relabel suffix from 'MoM' to 'vs avg' in email-tab and overview-tab.
- Treat values that round to 0.0% as neutral (no trend arrow/color)
  to prevent misleading '-0.0%' with a down arrow.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Replace off-brand bg-emerald-100/text-emerald-600 with the standard
bg-green-100/text-green-600 used by all other marketing KPI cards.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Move computeMomPct to @lfx-one/shared/utils alongside the other trend
helpers. Remove local copies from email-tab and performance-marketing-tab.
Also cache .at() values in email-tab open-rate calculation to eliminate
non-null assertions.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
- overview-tab: remove embedded sub-tab components that
  caused duplicate HTTP requests (per MRashad26)
- overview-tab: remove unused sub-tab component imports
- social-listening: sort merged mentions by date descending
  to prevent positive-mention bias in top-5 list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Weight engagement rate by impressions so high-volume platforms
contribute proportionally to the headline KPI.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Switch email type and campaign row data-testid attributes from raw
field values (emailType, name) to $index for stable, predictable
selectors that avoid collisions from duplicate names.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Drop the last (current, potentially incomplete) month from the
monthly impressions array before computing MoM percentage, so the
comparison only uses completed months — matching the ROAS KPI
query's cutoff behavior.

LFXV2-1644

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 19, 2026 04:06
@mrautela365 mrautela365 force-pushed the feat/LFXV2-1644-overview-all-sections branch from 58b3dbf to aa01e9c Compare May 19, 2026 04:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.html:45

  • The PR description says the Overview tab embeds all marketing impact sections (KPI → Attribution → Performance Marketing → Email → Web Activity → Social Accounts → Social Listening), but this template still only renders the KPI grid plus the attribution section. Either embed the remaining sections here (in the described order) or update the PR title/description to match the actual behavior.
      @for (kpi of performanceSummaryKpis(); track kpi.id) {
        <lfx-sparkline-kpi-card [kpi]="kpi" section="overview" />
      } @empty {
        <div class="col-span-full text-center py-8 text-sm text-gray-500" data-testid="overview-tab-kpi-empty">
          No performance data available for this period.
        </div>
      }
    }
  </div>
</div>

<lfx-attribution-section [foundationSlug]="foundationSlug()" [foundationName]="foundationName()" data-testid="overview-tab-attribution-section" />

const [impressionsResult, roasKpiResult, monthlyRoasResult, monthlyImpressionsResult, projectPerfResult, platformPerfResult] = await Promise.all([
this.snowflakeService.execute<{ TOTAL_IMPRESSIONS: number; TOTAL_SPEND: number; TOTAL_REVENUE: number }>(impressionsQuery, [foundationSlug]),
this.snowflakeService.execute<{ ROAS: number; ROAS_MOM_PCT: number }>(roasKpiQuery, [foundationSlug]),
this.snowflakeService.execute<{ CAMPAIGN_MONTH: string; ROAS: number }>(roasKpiQuery, [foundationSlug, foundationSlug]),
Comment on lines 83 to 95
switchMap((slug) => {
if (!slug) {
this.loading.set(false);
return of(null);
}
this.loading.set(true);
return this.analyticsService.getSocialReach(slug).pipe(
catchError(() => of(null)),
finalize(() => this.loading.set(false))
tap(() => this.loading.set(false)),
catchError(() => {
this.loading.set(false);
return of(null);
})
);
@dealako
Copy link
Copy Markdown
Contributor

dealako commented May 19, 2026

Hi Misha — this is a clean, well-structured PR with strong review responsiveness. Full pass below.


1. Independent Review

[minor] Impressions MoM compares partial current month to full prior month — performance-marketing-tab.component.ts:108

const impressionsMomPct = computeMomPct(data.monthlyData);

monthlyData comes from the server's monthlyImpressionsQuery, which has no upper date cutoff:

WHERE CAMPAIGN_MONTH >= DATEADD('MONTH', -6, DATE_TRUNC('MONTH', CURRENT_DATE()))

The sibling roasKpiQuery does exclude the current month:

AND CAMPAIGN_MONTH < DATE_TRUNC('MONTH', CURRENT_DATE())

If the current month has any rows (common day 1–28), computeMomPct will compare a partial month against a full prior month, likely surfacing a misleading drop on the KPI card. Fix options:

  • Add the same completed-month cutoff to monthlyImpressionsQuery in project.service.ts, or
  • Have the server compute impressions MoM alongside ROAS and return it as a pre-computed changePercentage field (matching the getRevenueImpact / getBrandReach pattern).

Agrees with Copilot at r3263461049 — not addressed in any subsequent commit.


[minor] PR description no longer matches the shipped implementation

The PR title is feat(dashboards): show all sections on overview tab and the body lists seven sections ("KPI cards → Attribution → Performance Marketing → Email → Web Activity → Social Accounts → Social Listening"). After commit 287cc1f1, the Overview tab shows only KPI cards + Attribution — the other five sections are accessible only via their individual focused tabs.

The squash-merge commit message will carry this description as-is. Please update the title (e.g., feat(dashboards): add kpi summary and attribution to overview tab) and the "Changes" section of the PR body to reflect what's actually shipping.


[nit] normalizePerformance called twice in initProjectRowsperformance-marketing-tab.component.ts:193-194

performance: this.normalizePerformance(p.performance),
performanceClass: this.getPerformanceClass(this.normalizePerformance(p.performance)),

initPlatformRows a few lines below handles this correctly:

const perf = this.normalizePerformance(p.performance);
performance: perf,
performanceClass: this.getPerformanceClass(perf),

Trivial consistency nit — no runtime impact.


[nit] Commit 287cc1f1 message describes a change not present in its diff

The commit body says: "social-listening: sort merged mentions by date descending to prevent positive-mention bias in top-5 list"

The diff for 287cc1f1 only touches overview-tab.component.{html,ts} (25 deletions, 1 insertion). social-listening-tab.component.ts's initTopMentions() interleaves positive/negative mentions with no date sort — the described change is absent from the code. If the sort is still needed, a follow-up commit should add it; if not, the commit message is misleading for future readers.


2. AI Comment Reconciliation

MRashad26 (structural concerns):

  • Duplicate getEmailCtr HTTP request → ✅ Resolved — embedded sub-tabs removed in 287cc1f1
  • Duplicate render trees / state loss on tab swap → ✅ Resolved — Overview no longer embeds focused-tab components

CodeRabbit / Copilot (previously raised):

  • ARIA table roles on email, social-accounts, web-activity, social-listening tables → ✅ Fixed
  • Unweighted social engagement rate → ✅ Fixed (impression-weighted in aecd2e5)
  • Duplicate revenueKeyMap in attribution-section → ✅ Fixed (only revenueKeyByModel remains)
  • Funnel filter passing empty/unknown stages → ✅ Fixed (!stage check added)
  • catchError missing on web-activity stream → ✅ Fixed
  • Number.isNaN!Number.isFinite in trend helpers → ✅ Fixed
  • -0.0% display edge case → ✅ Fixed (Math.abs(pct) < 0.05 guard)
  • Email CTR suffix 'MoM''vs avg' → ✅ Fixed
  • Email campaign data-testid collision risk → ✅ Fixed (index-based: email-campaign-row-${idx})
  • Composite track key for project rows → ✅ Fixed
  • Impressions MoM partial month (Copilot r3263461049) → ❌ Not addressed — flagged above as [minor]
  • Copilot "overview doesn't show all sections" (r3261028360, r3261490803) → N/A — PR intentionally pivoted

3. Revision Tracking

Previous MRashad26 review round raised two structural concerns. Both resolved:

Concern Resolving commit
Duplicate getEmailCtr HTTP request 287cc1f1
Duplicate render trees (all 6 tabs embedded in Overview) 287cc1f1

4. Summary

Misha, the body of work here is impressive — the marketing impact dashboard has gone from concept to a polished, production-ready feature across a tight sequence of PRs. The review responsiveness has been excellent: 15+ commits addressing bot and human feedback with clear commit messages and per-thread acknowledgment.

Issue counts: 0 blocking · 2 minor · 2 nits

Final decision: ✅ Approved with minor comments. The two minor items (#impressions MoM, #PR description) are worth addressing before merge — the MoM issue in particular can surface misleading drops for end users in the first week of each month. Neither is blocking if the team is comfortable shipping as-is, but I'd encourage a quick fix for the impressions query cutoff.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants