Conversation
…ncies - Introduced a new Labor Automation Hub page with sections for activity monitoring, job statistics, and methodology. - Added new components including ActivityCard, InfoPopover, LaborHubHeader, and TabGroup for enhanced UI functionality. - Integrated new data structures for risk and job forecasts. - Included new images for partner logos and added the `react-scrollspy-navigation` package for scroll navigation. - Updated package.json and package-lock.json to reflect new dependencies.
- Removed `react-scrollspy-navigation` from package.json and package-lock.json as it was not utilized in the project. - Updated the Tailwind configuration to support a more complex dark mode strategy. - Refactored the Labor Automation Hub page to incorporate new UI components such as DualPaneSectionCard, TableCompact, and HeroSection for improved layout and functionality. - Enhanced the LaborHubHeader and TabGroup components for better navigation experience. - Introduced InvertedThemeContainer for managing theme context in the application.
- Deleted unused partner images: `renphil-dark.png`, `renphil-light.webp`, and `sff-light.png`. - Updated `layout.tsx` to include `TailwindIndicator` for development visibility. - Refactored `LaborAutomationHubPage` to integrate `LaborHubNavigation` for improved navigation and layout consistency. - Removed `LaborHubHeader` and `LaborHubInfo` components, streamlining the page structure. - Enhanced `HeroSection` and `TabGroup` components for better responsiveness and visual appeal.
- Added a new Tailwind configuration file `tailwind.config.prettier.ts` to manage dark mode variants without altering class order. - Updated `.prettierrc.json` to include the new Tailwind configuration file. - Refactored `LaborHubNavigation` and `HeroSection` components for improved styling consistency and responsiveness.
- Introduced new OverviewSection and ResearchSection components for better content organization. - Updated layout and styling for various components, including ActivityMonitorSection and DualPaneSectionCard, to enhance responsiveness and visual appeal. - Added ContentParagraph component for consistent text formatting across sections. - Adjusted tab labels and removed outdated sections to reflect current content focus.
…atures - Introduced BasicQuestion and BarChart components for improved data visualization and interaction. - Updated LaborAutomationHubPage to utilize new components, enhancing the display of featured posts and questions. - Refactored ResearchSection to include AI vulnerability ratings and updated employment change data. - Improved the HeroSection with better SVG attributes for consistency. - Added QuestionCardContainer for better layout management of question cards.
- Removed the BarChart and QuestionCardContainer components to simplify the structure. - Introduced a new QuestionCard component for better layout and styling of question-related content. - Integrated RiskChart into the OverviewSection and ActivityMonitorSection for improved data representation. - Updated ActivityMonitorSection to utilize the new QuestionCard for displaying projected employment growth.
…tion - Introduced MultiLineRiskChart for enhanced data visualization of employment changes. - Updated OverviewSection to include the new chart, replacing the placeholder div for improved content representation. - Refactored LaborHubNavigation for better styling consistency.
…ance question card components - Replaced BasicQuestion component with QuestionLoader for improved data fetching and rendering of questions. - Introduced FlippableQuestionCard for enhanced user interaction with question content. - Added QuestionCardSkeleton for loading states while fetching question data. - Updated ActivityMonitorSection to use QuestionLoader for displaying projected employment growth. - Streamlined question card structure for better maintainability and performance.
…ctionality - Added a MoreButton to the QuestionCard component, providing users with options to view, export, share, and copy links. - Updated the QuestionCard to conditionally render the MoreButton based on the new showMoreButton prop. - Introduced POST_IDS_FILTER in filters to support filtering by IDs in search parameters. - Enhanced filters logic to handle both array and comma-separated string inputs for IDs.
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR introduces a comprehensive "Labor Automation Hub" feature with a new Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/Browser
participant Page as Labor Hub Page
participant Sections as Section Components
participant API as Data APIs
participant Chart as Chart Components
participant Hover as Chart Hover Context
User->>Page: Visit /labor-hub
Page->>API: Fetch overall employment data
Page->>API: Fetch jobs data with forecasts
API-->>Page: Return forecasted data
Page->>Sections: Render with data
Sections->>Chart: Initialize charts with data
Chart->>Hover: Provide hover context
User->>Chart: Hover over chart point
Chart->>Hover: Update hoverYear state
Hover-->>Chart: Broadcast hover state
Chart->>Chart: Highlight series/envelope
User->>Sections: Hover over activity marker
Sections->>Hover: Set hoveredActivityId
Hover-->>Chart: Activity highlight syncs
Chart->>Chart: Display marker styling
User->>Sections: Switch mobile tab
Sections->>Hover: Clear hoverYear/highlightedEnvelope
Chart->>Chart: Reset highlight state
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
Cleanup: Preview Environment RemovedThe preview environment for this PR has been destroyed.
Cleanup triggered by PR close at 2026-04-16T19:09:50Z |
- Refactored `MoreButton` and `QuestionCard` components to support multiple post IDs for actions like viewing, exporting, and sharing. - Enhanced the `QuestionCard` footer to include Metaculus attribution with the current date.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
front_end/src/app/(main)/labor-hub/components/question_cards/multi_question_line_chart.tsx (1)
224-238: Avoid repeated filtering/index lookup in historical tick thinning.Lines 230-232 rebuild and scan historical columns for every tick. Precomputing an index map once will reduce overhead and simplify the predicate.
♻️ Refactor sketch
+ const historicalIndexByLabel = new Map( + dataset.columns + .filter((column) => historicalLabelSet.has(column)) + .map((column, idx) => [column, idx] as const) + ); + const visibleXTickValues = historicalTickEvery && historicalTickEvery > 1 ? xTickValues.filter((xTickValue) => { const label = xTickLabelsByValue[String(xTickValue)]; if (!label || !historicalLabelSet.has(label)) return true; - - const historicalIndex = dataset.columns - .filter((column) => historicalLabelSet.has(column)) - .indexOf(label); + const historicalIndex = historicalIndexByLabel.get(label); return ( - historicalIndex === -1 || + historicalIndex == null || historicalIndex % historicalTickEvery === 0 ); }) : xTickValues;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_question_line_chart.tsx around lines 224 - 238, The filter for visibleXTickValues repeatedly rebuilds and searches dataset.columns for each tick; fix by precomputing a map of historical column label -> index once (e.g. before computing visibleXTickValues) using dataset.columns.filter(...) and building an object or Map, then in the predicate for visibleXTickValues use that lookup (referencing historicalLabelSet, xTickLabelsByValue, and historicalTickEvery) to get historicalIndex instead of calling .filter(...).indexOf(label) each time; ensure the predicate still returns true when label is missing or historicalIndex % historicalTickEvery === 0.front_end/src/app/(main)/labor-hub/components/labor_hub_navigation.tsx (1)
26-31: NarrownewsletterListKeyto the supported list keys.
newsletterListKey?: stringlets typos compile. Infront_end/src/app/(main)/actions.ts:17-24, an unknown key becomesundefined, andfront_end/src/services/api/misc/misc.server.ts:105-122then falls back to the default Mailjet list. That silently subscribes Labor Hub users to the wrong audience instead of failing fast. Please type this as a sharedNewsletterListKey/keyof typeof NEWSLETTER_LIST_IDS.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@front_end/src/app/`(main)/labor-hub/components/labor_hub_navigation.tsx around lines 26 - 31, The prop newsletterListKey on the LaborHubNavigation component is too permissive (string) causing silent fallback to the default Mailjet list; narrow its type to the shared union type (e.g., NewsletterListKey or keyof typeof NEWSLETTER_LIST_IDS) and import that type where the component is declared, then update any callers to pass only that typed key; ensure the shared type is the same one used by the logic in actions.ts and misc.server.ts so unknown keys become a compile error rather than runtime undefined/fallback.front_end/src/app/(main)/labor-hub/components/question_cards/multi_line_chart.tsx (1)
532-534: Keep badge formatting and axis formatting decoupled.Line 534 makes
formatYValuethe implicit fallback forformatYTick. That couples two separate props, and the badge formatter also feedscomputeMultiLineChartModel(), so a caller can't change badge text without also affecting tick text and left-padding calculation.Proposed fix
const formatResolvedYValue = formatYValueProp ?? defaultFormatYValue; - const formatResolvedYTick = - formatYTick ?? formatYValueProp ?? defaultFormatYTick; + const formatResolvedYTick = formatYTick ?? defaultFormatYTick;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_line_chart.tsx around lines 532 - 534, formatResolvedYTick currently falls back to formatYValueProp, coupling badge/label formatting with axis tick formatting; change formatResolvedYTick so it only uses formatYTick or defaultFormatYTick (i.e., remove formatYValueProp from the tick fallback) and ensure computeMultiLineChartModel continues to receive the badge formatter (formatYValueProp) separately so callers can change badge text without affecting axis ticks or left-padding calculations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_line_chart.tsx:
- Around line 517-520: The code builds highlightedX from
highlightedXProp/uncontrolledHighlightedX but usePrintOverride() only suppresses
hover badges, so hover state still affects rendering; create a
renderedHighlightedX that returns null when usePrintOverride() indicates print
mode (or otherwise forces no hover) and replace uses of highlightedX in the
x-tick formatter, x-axis tick emphasis logic, the vertical guide line render,
and DataPointCircle sizing/highlighting with renderedHighlightedX (look for
usages around the x-tick formatter, axis emphasis code, guide line drawing, and
DataPointCircle component calls such as those in the blocks mentioned) so that
in print mode those hover-only visuals are disabled.
- Around line 632-656: The pointer-move handler handleChartMouseMove currently
clears the shared highlight whenever the pointer enters the left/right gutter
(it calls setHighlightedX(null) in the offsetX-out-of-plot branch), which breaks
the shared hover year; update that branch to only clear the highlight when a
prop clearHighlightOnMouseLeave is true (otherwise just return without calling
setHighlightedX), and add clearHighlightOnMouseLeave to the hook dependency
array so the behavior follows the prop passed from labor_hub_multi_line_chart.
In
`@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_question_line_chart.tsx:
- Around line 217-223: historicalLabelSet is currently derived from rows while
the chart builds historical points from dataset.rows, which can cause
divider/tick drift when resolution changes; change the source-of-truth so the
set is built from dataset.rows (i.e., use Object.keys(row.historicalValues ??
{}) for each row in dataset.rows instead of rows) and pass that resulting set
into getHistoricalForecastDividerX along with dataset.columns so divider/tick
logic and the rendered historical points use the same data source (update the
usage of historicalLabelSet, rows, dataset.rows, and
getHistoricalForecastDividerX accordingly).
In `@front_end/src/app/`(main)/labor-hub/components/scrollspy_button_group.tsx:
- Around line 22-29: The buttons are only visually indicating the active section
via the data-active attribute; update the button rendering in
scrollspy_button_group.tsx to mirror that state into an ARIA attribute so
assistive tech can detect it: when the button with
data-scrollspy-anchor={item.id} is marked active (data-active="true"), set
aria-current="location" (and remove/set it when not active) — implement this by
adding a conditional aria-current prop tied to the same active condition used
for the data-active class toggling in the component.
---
Nitpick comments:
In `@front_end/src/app/`(main)/labor-hub/components/labor_hub_navigation.tsx:
- Around line 26-31: The prop newsletterListKey on the LaborHubNavigation
component is too permissive (string) causing silent fallback to the default
Mailjet list; narrow its type to the shared union type (e.g., NewsletterListKey
or keyof typeof NEWSLETTER_LIST_IDS) and import that type where the component is
declared, then update any callers to pass only that typed key; ensure the shared
type is the same one used by the logic in actions.ts and misc.server.ts so
unknown keys become a compile error rather than runtime undefined/fallback.
In
`@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_line_chart.tsx:
- Around line 532-534: formatResolvedYTick currently falls back to
formatYValueProp, coupling badge/label formatting with axis tick formatting;
change formatResolvedYTick so it only uses formatYTick or defaultFormatYTick
(i.e., remove formatYValueProp from the tick fallback) and ensure
computeMultiLineChartModel continues to receive the badge formatter
(formatYValueProp) separately so callers can change badge text without affecting
axis ticks or left-padding calculations.
In
`@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_question_line_chart.tsx:
- Around line 224-238: The filter for visibleXTickValues repeatedly rebuilds and
searches dataset.columns for each tick; fix by precomputing a map of historical
column label -> index once (e.g. before computing visibleXTickValues) using
dataset.columns.filter(...) and building an object or Map, then in the predicate
for visibleXTickValues use that lookup (referencing historicalLabelSet,
xTickLabelsByValue, and historicalTickEvery) to get historicalIndex instead of
calling .filter(...).indexOf(label) each time; ensure the predicate still
returns true when label is missing or historicalIndex % historicalTickEvery ===
0.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2433e559-12fe-401c-bd9a-763107cc52ed
📒 Files selected for processing (10)
front_end/src/app/(main)/labor-hub/components/labor_hub_navigation.tsxfront_end/src/app/(main)/labor-hub/components/mobile_carousel.tsxfront_end/src/app/(main)/labor-hub/components/question_cards/basic_question.tsxfront_end/src/app/(main)/labor-hub/components/question_cards/multi_line_chart.tsxfront_end/src/app/(main)/labor-hub/components/question_cards/multi_question_line_chart.tsxfront_end/src/app/(main)/labor-hub/components/question_cards/question.tsxfront_end/src/app/(main)/labor-hub/components/scrollspy_button_group.tsxfront_end/src/app/(main)/labor-hub/page.tsxfront_end/src/app/(main)/labor-hub/sections/activity_monitor.tsxfront_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/prediction/single_question_prediction/continuous_question_prediction.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
- front_end/src/app/(main)/labor-hub/components/mobile_carousel.tsx
- front_end/src/app/(main)/labor-hub/components/question_cards/question.tsx
- front_end/src/app/(main)/labor-hub/page.tsx
- front_end/src/app/(main)/labor-hub/sections/activity_monitor.tsx
- front_end/src/app/(main)/labor-hub/components/question_cards/basic_question.tsx
| const highlightedX = | ||
| highlightedXProp === undefined | ||
| ? uncontrolledHighlightedX | ||
| : highlightedXProp; |
There was a problem hiding this comment.
Print mode still renders hover artifacts.
usePrintOverride() only suppresses hover badges right now. A non-null highlightedX still changes tick visibility, bolds the active x tick, enlarges points, and draws the guide line, so printing after a hover can bake a transient active year into the chart.
Proposed fix
const highlightedX =
highlightedXProp === undefined
? uncontrolledHighlightedX
: highlightedXProp;
+ const renderedHighlightedX = isPrintMode ? null : highlightedX;Then use renderedHighlightedX instead of highlightedX anywhere the UI renders hover-only state: the x-tick formatter, x-axis tick emphasis, the vertical guide line, and DataPointCircle.
Also applies to: 664-699, 748-755, 816-831, 919-920
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@front_end/src/app/`(main)/labor-hub/components/question_cards/multi_line_chart.tsx
around lines 517 - 520, The code builds highlightedX from
highlightedXProp/uncontrolledHighlightedX but usePrintOverride() only suppresses
hover badges, so hover state still affects rendering; create a
renderedHighlightedX that returns null when usePrintOverride() indicates print
mode (or otherwise forces no hover) and replace uses of highlightedX in the
x-tick formatter, x-axis tick emphasis logic, the vertical guide line render,
and DataPointCircle sizing/highlighting with renderedHighlightedX (look for
usages around the x-tick formatter, axis emphasis code, guide line drawing, and
DataPointCircle component calls such as those in the blocks mentioned) so that
in print mode those hover-only visuals are disabled.
Summary by CodeRabbit
New Features
Improvements