Skip to content

[OSDEV-2374] Implement claim banner with status and cta support#890

Merged
VadimKovalenkoSNF merged 28 commits intomainfrom
OSDEV-2374-implement-claim-banner-with-status-and-CTA-support
Mar 3, 2026
Merged

[OSDEV-2374] Implement claim banner with status and cta support#890
VadimKovalenkoSNF merged 28 commits intomainfrom
OSDEV-2374-implement-claim-banner-with-status-and-CTA-support

Conversation

@VadimKovalenkoSNF
Copy link
Contributor

@VadimKovalenkoSNF VadimKovalenkoSNF commented Feb 26, 2026

Implements OSDEV-2374

Created UI for Claim and Closure status banners.

Additional:

  1. Improved the <DialogTooltip/> component so that it does not close the popup on mouseover. This change allows users to access the Learn more → link.
  2. Passed the isEmbed prop to the <ClaimFlag/> component. Although we redirect to the legacy facility page in embed mode, this serves as an additional guard to prevent claiming locations from embed mode.
  3. Experimental: Introduced custom getTypographyStyles to make sure common style rules will be reused across other components.

@VadimKovalenkoSNF VadimKovalenkoSNF self-assigned this Feb 26, 2026
@barecheck
Copy link

barecheck bot commented Feb 26, 2026

React App | Jest test suite - Code coverage report

Total: 41.22%

Your code coverage diff: 0.68% ▴

✅ All code changes are covered

@barecheck
Copy link

barecheck bot commented Feb 26, 2026

Countries App | Unittest test suite - Code coverage report

Total: 100%

Your code coverage diff: 0.00% ▴

✅ All code changes are covered

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

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

Walkthrough

Adds an optional interactive DialogTooltip (with learn-more link), refactors ClaimFlag into a Grid-based component that surfaces claimInfo and formatted dates, updates related styles and utilities (typography + date formatting), propagates claim/embed state into ProductionLocationDetailsContent, adjusts ClosureStatus layout/text, and adds unit tests and a release note.

Changes

Cohort / File(s) Summary
Dialog Tooltip
src/react/src/components/Contribute/DialogTooltip.jsx
Adds interactive and learnMoreHref props; manages internal open state, leave-delay timer and cleanup, UUID aria id, conditional trigger wrapper for keyboard/focus, conditional Popper/arrow/handlers, updated PropTypes/defaultProps.
Claim Flag Component
src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx
Reworked UI to Material-UI Grid; accepts claimInfo and isEmbed; renders claim status row, optional secondary line (claim link or "claimed by" with formatted date), info icon using DialogTooltip, updated imports and PropTypes/defaultProps.
Claim Flag Styles
src/react/src/components/ProductionLocation/Heading/ClaimFlag/styles.js
Rewrote style factory to use theme spacing and centralized typography; added many new classes (icon/status variants, layout tokens) and removed legacy state-based keys.
Claim Flag Utils
src/react/src/components/ProductionLocation/Heading/ClaimFlag/utils.js
Removed getBackgroundColorClass; changed getMainText claimed text to CLAIMED PROFILE; added formatClaimDate(date) (moment-based).
Production Location Details
src/react/src/components/ProductionLocation/ProductionLocationDetailsContent/ProductionLocationDetailsContent.jsx
Adds embed prop (mapped from state), normalizes/redirects OS ID, derives isPendingClaim/isClaimed from claim_info, passes claimInfo/isEmbed to ClaimFlag; PropTypes/defaults updated.
Closure Status
src/react/src/components/ProductionLocation/Heading/ClosureStatus/...
DOM/class adjustments and punctuation fixes; added iconColumn style and layout/alignment updates to match new ClaimFlag layout; PropTypes/defaultProps added.
Typography Utility
src/react/src/util/typographyStyles.js
New getTypographyStyles(theme) returning frozen typography tokens (form labels, section titles, bodyText, etc.); exported named and default.
Tests
src/react/src/__tests__/components/ProductionLocationClaimFlag.test.jsx, src/react/src/__tests__/components/ProductionLocationClosureStatus.test.jsx
Adds tests covering claimed/unclaimed/pending flows, claimInfo rendering (contributor/approved_at), embed behavior, and closure status scenarios.
Docs
doc/release/RELEASE-NOTES.md
Added release note entry referencing Claim status banner (Release 2.20.0).

Sequence Diagram(s)

(Skipped — UI/component updates only; no multi-system sequential flow rendered.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • roman-stolar
  • protsack-stephan
  • mazursasha1990
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main implementation goal: adding a claim banner UI with status and CTA support, which aligns with the primary changes in DialogTooltip, ClaimFlag, and related styling updates.
Description check ✅ Passed The pull request description clearly describes the implementation of OSDEV-2374 for UI claim and closure status banners, with specific additional improvements to DialogTooltip, isEmbed propagation, and typography utilities.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch OSDEV-2374-implement-claim-banner-with-status-and-CTA-support

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@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 (2)
src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx (1)

235-241: Include approved_at in claimInfo PropTypes.

approved_at is used at runtime but not declared in the prop contract, which weakens payload validation/documentation.

♻️ Proposed fix
     claimInfo: PropTypes.shape({
         contributor: PropTypes.oneOfType([
             PropTypes.string,
             PropTypes.shape({ name: PropTypes.string }),
         ]),
+        approved_at: PropTypes.string,
         created_at: PropTypes.string,
     }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx`
around lines 235 - 241, The PropTypes for claimInfo in the ClaimFlag component
are missing the approved_at field used at runtime; update the PropTypes.shape
for claimInfo in ClaimFlag.jsx to include approved_at (e.g., approved_at:
PropTypes.string) so the prop contract validates/documentates this timestamp
field alongside contributor and created_at.
src/react/src/components/ProductionLocation/Heading/ClaimFlag/styles.js (1)

5-31: Use the computed spacing token consistently.

spacing has a fallback, but paddingRight still uses theme.spacing.unit directly. Use spacing there too to keep fallback behavior coherent.

♻️ Proposed fix
-            paddingRight: theme.spacing.unit * 1.5,
+            paddingRight: spacing * 1.5,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/styles.js`
around lines 5 - 31, The computed spacing fallback variable is declared as
spacing but paddingRight in the iconColumn still uses theme.spacing.unit
directly; update paddingRight to use the spacing variable (e.g., spacing * 1.5)
so the fallback is applied consistently, and scan other style props in the
returned object (root, row, iconColumn) to replace any remaining
theme.spacing.unit uses with spacing; reference the spacing const and the
iconColumn object in this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/react/src/components/Contribute/DialogTooltip.jsx`:
- Around line 1-38: A pending interactive close timeout (stored in
closeTimerRef) can fire after the component unmounts and call setOpen(false);
fix this by ensuring any scheduled timeout is cleared before setting a new one
and on unmount: update handleTriggerLeave to call clearCloseTimer() before
assigning closeTimerRef.current, and add a useEffect cleanup that calls
clearCloseTimer() when the component unmounts; reference closeTimerRef,
clearCloseTimer, handleTriggerLeave and setOpen so the timeout is always cleared
to prevent stale setOpen calls.
- Around line 94-113: When interactive is true, the trigger wrapper only reacts
to mouse events so keyboard users cannot open the Tooltip; update the trigger
wrapper (the span around childComponent used in triggerWrapper) to be
keyboard-accessible by adding tabIndex={0}, onFocus={() => setOpen(true)},
onBlur={() => setOpen(false)} (and optionally onKeyDown to open on Enter/Space)
alongside the existing handleTriggerEnter/handleTriggerLeave, and ensure the
controlled open prop (open) and onClose handler on Tooltip remain consistent;
also add an aria-describedby (or id) connection between the trigger and Tooltip
titleContent so assistive tech can associate them.

In
`@src/react/src/components/ProductionLocation/ProductionLocationDetailsContent/ProductionLocationDetailsContent.jsx`:
- Around line 107-110: The logic for computing isClaimed is wrong: update the
checks (in ProductionLocationDetailsContent.jsx's isPendingClaim/isClaimed and
the analogous code in FacilityDetailsContent.jsx) so that isClaimed is true only
when data?.properties?.claim_info?.status ===
facilityClaimStatusChoicesEnum.APPROVED (and isPendingClaim remains the PENDING
check); replace the current negation-based check (!!data?.properties?.claim_info
&& !isPendingClaim) with an explicit status equality to
facilityClaimStatusChoicesEnum.APPROVED to avoid treating DENIED or REVOKED as
claimed.

---

Nitpick comments:
In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx`:
- Around line 235-241: The PropTypes for claimInfo in the ClaimFlag component
are missing the approved_at field used at runtime; update the PropTypes.shape
for claimInfo in ClaimFlag.jsx to include approved_at (e.g., approved_at:
PropTypes.string) so the prop contract validates/documentates this timestamp
field alongside contributor and created_at.

In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/styles.js`:
- Around line 5-31: The computed spacing fallback variable is declared as
spacing but paddingRight in the iconColumn still uses theme.spacing.unit
directly; update paddingRight to use the spacing variable (e.g., spacing * 1.5)
so the fallback is applied consistently, and scan other style props in the
returned object (root, row, iconColumn) to replace any remaining
theme.spacing.unit uses with spacing; reference the spacing const and the
iconColumn object in this change.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0299fbe and b738170.

📒 Files selected for processing (6)
  • src/react/src/components/Contribute/DialogTooltip.jsx
  • src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx
  • src/react/src/components/ProductionLocation/Heading/ClaimFlag/styles.js
  • src/react/src/components/ProductionLocation/Heading/ClaimFlag/utils.js
  • src/react/src/components/ProductionLocation/ProductionLocationDetailsContent/ProductionLocationDetailsContent.jsx
  • src/react/src/util/typographyStyles.js

@barecheck
Copy link

barecheck bot commented Feb 26, 2026

Contricleaner App | Unittest test suite - Code coverage report

Total: 98.75%

Your code coverage diff: 0.00% ▴

✅ All code changes are covered

Copy link

@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.

🧹 Nitpick comments (2)
src/react/src/components/Contribute/DialogTooltip.jsx (1)

75-99: Factor duplicated popperOptions into a single base object.

Both branches repeat the same arrow modifier config; extracting it will reduce noise and future drift risk.

♻️ Proposed refactor
+    const basePopperProps = {
+        popperOptions: {
+            modifiers: {
+                arrow: {
+                    enabled: Boolean(arrowRef),
+                    element: arrowRef,
+                },
+            },
+        },
+    };
+
     const popperProps = interactive
         ? {
               onMouseEnter: handlePopperEnter,
               onMouseLeave: handlePopperLeave,
               onFocus: handlePopperEnter,
               onBlur: handlePopperLeave,
-              popperOptions: {
-                  modifiers: {
-                      arrow: {
-                          enabled: Boolean(arrowRef),
-                          element: arrowRef,
-                      },
-                  },
-              },
+              ...basePopperProps,
           }
-        : {
-              popperOptions: {
-                  modifiers: {
-                      arrow: {
-                          enabled: Boolean(arrowRef),
-                          element: arrowRef,
-                      },
-                  },
-              },
-          };
+        : basePopperProps;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/react/src/components/Contribute/DialogTooltip.jsx` around lines 75 - 99,
The popperOptions block is duplicated in the construction of popperProps;
extract a single base object (e.g., const basePopperOptions = { popperOptions: {
modifiers: { arrow: { enabled: Boolean(arrowRef), element: arrowRef } } } };)
and then create popperProps by spreading basePopperOptions into both branches,
adding the interactive handlers only when interactive is true (use
handlePopperEnter and handlePopperLeave for
onMouseEnter/onMouseLeave/onFocus/onBlur). Ensure references to popperProps and
arrowRef remain unchanged.
src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx (1)

153-217: Consider extracting claimed-by text composition into a small helper.

This conditional block is correct but hard to scan; moving it into a renderer/helper would improve readability and testability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx`
around lines 153 - 217, Extract the JSX that composes the claimed-by text into a
small helper inside the ClaimFlag component (e.g., a function named
renderClaimedByText or getClaimedByNode) that accepts contributorName and
formattedDate and returns the appropriate JSX node using
classes.subtitleSameLine and classes.inlineHighlight; replace the large
conditional block inside the showClaimedByLine Typography with a single call to
this helper, and ensure the helper is exported or unit-testable if needed for
test coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/react/src/components/Contribute/DialogTooltip.jsx`:
- Around line 75-99: The popperOptions block is duplicated in the construction
of popperProps; extract a single base object (e.g., const basePopperOptions = {
popperOptions: { modifiers: { arrow: { enabled: Boolean(arrowRef), element:
arrowRef } } } };) and then create popperProps by spreading basePopperOptions
into both branches, adding the interactive handlers only when interactive is
true (use handlePopperEnter and handlePopperLeave for
onMouseEnter/onMouseLeave/onFocus/onBlur). Ensure references to popperProps and
arrowRef remain unchanged.

In `@src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx`:
- Around line 153-217: Extract the JSX that composes the claimed-by text into a
small helper inside the ClaimFlag component (e.g., a function named
renderClaimedByText or getClaimedByNode) that accepts contributorName and
formattedDate and returns the appropriate JSX node using
classes.subtitleSameLine and classes.inlineHighlight; replace the large
conditional block inside the showClaimedByLine Typography with a single call to
this helper, and ensure the helper is exported or unit-testable if needed for
test coverage.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b60b17 and e07a9ed.

📒 Files selected for processing (4)
  • src/react/src/__tests__/components/ProductionLocationClosureStatus.test.jsx
  • src/react/src/components/Contribute/DialogTooltip.jsx
  • src/react/src/components/ProductionLocation/Heading/ClaimFlag/ClaimFlag.jsx
  • src/react/src/components/ProductionLocation/Heading/ClosureStatus/ClosureStatus.jsx
✅ Files skipped from review due to trivial changes (1)
  • src/react/src/tests/components/ProductionLocationClosureStatus.test.jsx

Copy link
Collaborator

@protsack-stephan protsack-stephan left a comment

Choose a reason for hiding this comment

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

Great work! Couple of structural comments from me!

Copy link
Collaborator

@protsack-stephan protsack-stephan left a comment

Choose a reason for hiding this comment

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

Good work! Couple of comments from me, it's up to you to decide whether to implement them or leave them as is.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

Copy link
Collaborator

@protsack-stephan protsack-stephan left a comment

Choose a reason for hiding this comment

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

Looks good!

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.

3 participants