Skip to content

Wire PRT program-rules fixtures into Storybook - #24

Merged
nnkogift merged 2 commits into
mainfrom
feature/wire-program-rules-storybook-demo
Aug 5, 2026
Merged

nnkogift merged 2 commits into
mainfrom
feature/wire-program-rules-storybook-demo

Conversation

@nnkogift

@nnkogift nnkogift commented Aug 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Replaces the ANC/Child Programme Storybook demos with an Event Program Rules and a Tracker Program Rules demo driven by the new PRT fixtures (event-program-rules-example.json / tracker-program-rules-example.json), which exercise nearly every program-rule action type (HIDEFIELD, HIDESECTION, ASSIGN, SETMANDATORYFIELD, SHOWWARNING/SHOWERROR, HIDEOPTION/HIDEOPTIONGROUP/SHOWOPTIONGROUP, DISPLAYTEXT/DISPLAYKEYVALUEPAIR), across all 3 UI adapters (dhis2-ui, mantine, mui).
  • Adds apps/storybook/fixtures/metadataExport.ts, a denormalizer that turns the fixtures' flat DHIS2 metadata-export shape into the pre-joined shape resolveEventProgramMetadata/resolveTrackerProgramMetadata expect (no existing helper did this).
  • Threads optionGroups into withEventForm/useEventForm so HIDEOPTIONGROUP/SHOWOPTIONGROUP have group-membership data to resolve against, and adds an optional Feedback slot to ProgrammeEventForm/ProgrammeRegistrationForm for DISPLAYTEXT/DISPLAYKEYVALUEPAIR.
  • Fixes a pre-existing Mantine adapter bug surfaced by the new stories: D2BooleanField passed field.value straight to Mantine's SegmentedControl, so an unset boolean field (no defaultValues supplied) silently fell back to Mantine's first-item default and rendered as "Yes".
  • Adds a storybook entry to .claude/launch.json and scopes .fallowrc.json's duplication check away from apps/storybook/stories/** (the per-adapter story trio pattern is intentional repo-wide duplication).

Test plan

  • pnpm --filter storybook test — 101/101 interaction tests pass across dhis2-ui/mantine/mui
  • pnpm typecheck — clean across all workspace packages
  • pnpm lint — clean (eslint + prettier) on all touched files
  • Manually exercised every new story in a live Storybook preview to confirm rule effects render correctly
  • fallow audit — passes (no newly introduced dead code, complexity, or duplication)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added interactive Storybook examples for event-program and tracker-program rules across DHIS2 UI, Mantine, and MUI.
    • Examples demonstrate conditional visibility, validation warnings and errors, calculated values, required fields, option filtering, feedback, and submission.
    • Forms can now display optional feedback content before submission.
  • Bug Fixes
    • Improved boolean field handling when no value is provided.
  • Chores
    • Added a convenient Storybook development launch configuration and refreshed demonstration fixtures.

…d Programme demos

Replaces the ANC/Child Programme Storybook demos with an event-program-rules
and a tracker-program-rules demo driven by the new PRT fixtures, which
exercise nearly every program-rule action type. Adds a metadata-export
denormalizer since the fixtures are flat metadata-export packages rather
than the pre-joined shape the resolvers expect, threads `optionGroups`
into `useEventForm` so HIDEOPTIONGROUP/SHOWOPTIONGROUP have something to
resolve against, and adds an optional Feedback slot to the shared form
components for DISPLAYTEXT/DISPLAYKEYVALUEPAIR.

Also fixes a Mantine adapter bug found via the new stories: D2BooleanField
passed field.value straight to SegmentedControl, so an unset boolean field
fell back to Mantine's first-item default and silently rendered as "Yes".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nnkogift, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 53 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d1ebd06-f1aa-45f0-9c20-65376ce1242c

📥 Commits

Reviewing files that changed from the base of the PR and between b4970c3 and 28d1222.

📒 Files selected for processing (1)
  • apps/storybook/fixtures/tracker-program-rules-example.json
📝 Walkthrough

Walkthrough

Added event and tracker program-rule fixtures, metadata resolvers, shared adapter interactions, and Storybook stories for DHIS2 UI, Mantine, and MUI. Added optional form feedback and option-group support. Removed legacy Storybook examples and interactions.

Changes

Program-rules Storybook coverage

Layer / File(s) Summary
Metadata fixture resolution
apps/storybook/fixtures/metadataExport.ts, apps/storybook/fixtures/event-program-rules-example.json, apps/storybook/fixtures/eventProgramRules.ts, apps/storybook/fixtures/tracker-program-rules-example.json, apps/storybook/fixtures/trackerProgramRules.ts
Added metadata conversion utilities and complete event and tracker program-rule fixtures.
Form feedback and option-group wiring
apps/storybook/components/ProgrammeEventForm.tsx, apps/storybook/components/ProgrammeRegistrationForm.tsx, apps/storybook/decorators/withEventForm.tsx, components/mantine/src/fields/widgets/ChoiceFields.tsx
Forms optionally render Feedback. Event decorators pass optionGroups to useEventForm. Mantine boolean fields handle undefined values.
Adapter-aware interaction plays
apps/storybook/interactions/eventProgramRulesInteractions.ts, apps/storybook/interactions/trackerProgramRulesInteractions.ts
Added shared interaction scenarios for visibility, validation, assignments, mandatory fields, option filtering, feedback, and submission across three adapters.
Adapter-specific Storybook suites
apps/storybook/stories/*/EventProgramRulesForm.stories.tsx, apps/storybook/stories/*/TrackerProgramRulesForm.stories.tsx, .claude/launch.json, .fallowrc.json
Added event and tracker program-rule stories for DHIS2 UI, Mantine, and MUI. Added a Storybook launch command and ignored Storybook stories in duplicate detection. Legacy ANC and child-programme fixtures, interactions, and stories were removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StorybookPlay
  participant ProgrammeEventForm
  participant useEventForm
  participant MetadataFixture
  participant Feedback
  StorybookPlay->>ProgrammeEventForm: Render form and enter rule inputs
  ProgrammeEventForm->>useEventForm: Update event values
  useEventForm->>MetadataFixture: Resolve program rules and option groups
  MetadataFixture-->>useEventForm: Return resolved metadata
  useEventForm-->>ProgrammeEventForm: Apply visibility, validation, and assignments
  ProgrammeEventForm->>Feedback: Render feedback and indicators
  StorybookPlay->>ProgrammeEventForm: Submit form
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main addition of PRT program-rules fixtures to Storybook, although it does not mention the replacement demos or supporting API changes.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/wire-program-rules-storybook-demo

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.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Left a non-blocking comment: Cursor Security Agent finished as skipped, so required automated security review did not complete successfully and this PR is not approved. Cursor Bugbot was not present on the PR checks. Human review is needed; no reviewers were assigned because the only assignable user is the PR author.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
apps/storybook/interactions/eventProgramRulesInteractions.ts (1)

68-116: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared adapter helpers into one module.

MANTINE_BOOLEAN_SEGMENT_VALUE, clickMantineBooleanSegment, pickBooleanOption, findFeedbackText, canvasOf, Canvas, StoryPlayContext, and StoryPlay are duplicated in apps/storybook/interactions/trackerProgramRulesInteractions.ts. The two copies have already diverged: this file resolves the portalled dhis2-ui option with screen.findByText on Line 104, while the tracker copy uses within(document.body).findByText.

.fallowrc.json ignores only apps/storybook/stories/** and sets minOccurrences: 3, so a two-file clone stays invisible to the duplication check.

Move these helpers into a shared module, for example apps/storybook/interactions/adapterHelpers.ts, and parameterize the adapter union once.

🤖 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/storybook/interactions/eventProgramRulesInteractions.ts` around lines 68
- 116, Extract MANTINE_BOOLEAN_SEGMENT_VALUE, clickMantineBooleanSegment,
pickBooleanOption, findFeedbackText, canvasOf, Canvas, StoryPlayContext, and
StoryPlay into a shared adapterHelpers module, defining the adapter union there
once. Update both eventProgramRulesInteractions.ts and
trackerProgramRulesInteractions.ts to import and reuse these helpers, preserving
the existing DHIS2 portalled-option behavior and removing the duplicated
definitions.
apps/storybook/fixtures/metadataExport.ts (1)

439-453: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the raw fixture object casts with satisfies.

buildRawEventProgramConfig and buildRawTrackerConfig both return shaped objects already annotated with RawEventProgramConfigResult and RawTrackerConfigResult; the as casts bypass structural checks if either raw config type changes. Use satisfies at these return sites so shape drift fails at compile time.

🤖 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/storybook/fixtures/metadataExport.ts` around lines 439 - 453, Replace
the `as RawEventProgramConfigResult` cast on the object returned by
`buildRawEventProgramConfig` with a `satisfies RawEventProgramConfigResult`
check, and make the same change for the return object in `buildRawTrackerConfig`
using `RawTrackerConfigResult`. Preserve the existing object shapes while
ensuring TypeScript validates them structurally.
🤖 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/storybook/fixtures/tracker-program-rules-example.json`:
- Around line 748-766: Update the fixture so section ykSoYFhrMb1 is attached to
follow-up stage xizfjWb34Ed: add the stage reference to the section and include
the section ID in that stage’s programStageSections list. Preserve the existing
HIDESECTION rule PRT-T16 so the tracker demo renders and covers its target; only
remove the section and rule if the fixture intentionally omits stage-level
forms.

In `@apps/storybook/interactions/eventProgramRulesInteractions.ts`:
- Around line 212-237: The fallback branch of showWarningAboveHundred in
apps/storybook/interactions/eventProgramRulesInteractions.ts lines 212-237 must
assert NUMBER_EXCEEDS_WARNING rather than rechecking the input value. Apply the
same change to the fallback branch of the corresponding age-warning play in
apps/storybook/interactions/trackerProgramRulesInteractions.ts lines 156-181,
asserting AGE_IMPLAUSIBLE_WARNING; add adapter-specific warning selectors if
mantine or mui render the warning differently, without replacing these checks
with input-value assertions.

---

Nitpick comments:
In `@apps/storybook/fixtures/metadataExport.ts`:
- Around line 439-453: Replace the `as RawEventProgramConfigResult` cast on the
object returned by `buildRawEventProgramConfig` with a `satisfies
RawEventProgramConfigResult` check, and make the same change for the return
object in `buildRawTrackerConfig` using `RawTrackerConfigResult`. Preserve the
existing object shapes while ensuring TypeScript validates them structurally.

In `@apps/storybook/interactions/eventProgramRulesInteractions.ts`:
- Around line 68-116: Extract MANTINE_BOOLEAN_SEGMENT_VALUE,
clickMantineBooleanSegment, pickBooleanOption, findFeedbackText, canvasOf,
Canvas, StoryPlayContext, and StoryPlay into a shared adapterHelpers module,
defining the adapter union there once. Update both
eventProgramRulesInteractions.ts and trackerProgramRulesInteractions.ts to
import and reuse these helpers, preserving the existing DHIS2 portalled-option
behavior and removing the duplicated definitions.
🪄 Autofix

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 Plus

Run ID: 03e75e56-430f-44bb-ae9a-335d7d9b73dd

📥 Commits

Reviewing files that changed from the base of the PR and between c7088c9 and b4970c3.

📒 Files selected for processing (38)
  • .claude/launch.json
  • .fallowrc.json
  • apps/storybook/components/ProgrammeEventForm.tsx
  • apps/storybook/components/ProgrammeRegistrationForm.tsx
  • apps/storybook/decorators/withEventForm.tsx
  • apps/storybook/fixtures/anc.event.json
  • apps/storybook/fixtures/anc.stage.json
  • apps/storybook/fixtures/anc.ts
  • apps/storybook/fixtures/child-programme.event.json
  • apps/storybook/fixtures/child-programme.stage.json
  • apps/storybook/fixtures/child-programme.tracker.json
  • apps/storybook/fixtures/childProgramme.ts
  • apps/storybook/fixtures/event-program-rules-example.json
  • apps/storybook/fixtures/eventProgramRules.ts
  • apps/storybook/fixtures/metadataExport.ts
  • apps/storybook/fixtures/tracker-program-rules-example.json
  • apps/storybook/fixtures/trackerProgramRules.ts
  • apps/storybook/interactions/ancInteractions.ts
  • apps/storybook/interactions/childProgrammeInteractions.ts
  • apps/storybook/interactions/childProgrammeRegistrationInteractions.ts
  • apps/storybook/interactions/eventProgramRulesInteractions.ts
  • apps/storybook/interactions/trackerProgramRulesInteractions.ts
  • apps/storybook/stories/dhis2-ui/AncForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/ChildProgrammeForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/EventProgramRulesForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/TrackerProgramRulesForm.stories.tsx
  • apps/storybook/stories/mantine/AncForm.stories.tsx
  • apps/storybook/stories/mantine/ChildProgrammeForm.stories.tsx
  • apps/storybook/stories/mantine/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/mantine/EventProgramRulesForm.stories.tsx
  • apps/storybook/stories/mantine/TrackerProgramRulesForm.stories.tsx
  • apps/storybook/stories/mui/AncForm.stories.tsx
  • apps/storybook/stories/mui/ChildProgrammeForm.stories.tsx
  • apps/storybook/stories/mui/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/mui/EventProgramRulesForm.stories.tsx
  • apps/storybook/stories/mui/TrackerProgramRulesForm.stories.tsx
  • components/mantine/src/fields/widgets/ChoiceFields.tsx
💤 Files with no reviewable changes (19)
  • apps/storybook/fixtures/anc.ts
  • apps/storybook/stories/mui/AncForm.stories.tsx
  • apps/storybook/fixtures/anc.event.json
  • apps/storybook/fixtures/child-programme.tracker.json
  • apps/storybook/fixtures/anc.stage.json
  • apps/storybook/fixtures/child-programme.event.json
  • apps/storybook/interactions/childProgrammeInteractions.ts
  • apps/storybook/stories/mantine/AncForm.stories.tsx
  • apps/storybook/stories/mantine/ChildProgrammeForm.stories.tsx
  • apps/storybook/stories/mantine/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/AncForm.stories.tsx
  • apps/storybook/interactions/childProgrammeRegistrationInteractions.ts
  • apps/storybook/stories/dhis2-ui/ChildProgrammeForm.stories.tsx
  • apps/storybook/stories/dhis2-ui/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/mui/ChildProgrammeRegistrationForm.stories.tsx
  • apps/storybook/stories/mui/ChildProgrammeForm.stories.tsx
  • apps/storybook/interactions/ancInteractions.ts
  • apps/storybook/fixtures/childProgramme.ts
  • apps/storybook/fixtures/child-programme.stage.json

Comment thread apps/storybook/fixtures/tracker-program-rules-example.json
Comment thread apps/storybook/interactions/eventProgramRulesInteractions.ts
…ixture

The "Hideable follow-up section" (ykSoYFhrMb1) had no programStage back-
reference, and the Follow-up stage listed no programStageSections, so the
PRT-T16 HIDESECTION rule pointed at a section no stage could ever render.
Mirrors the event fixture's section<->stage linkage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Left a non-blocking comment: Cursor Security Agent finished as skipped, so required automated security review did not complete successfully and this PR is not approved. Cursor Bugbot was not present on the PR checks. Human review is needed; no reviewers were assigned because the only assignable collaborator is the PR author.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@nnkogift
nnkogift merged commit ba43705 into main Aug 5, 2026
14 checks passed
@nnkogift
nnkogift deleted the feature/wire-program-rules-storybook-demo branch August 5, 2026 05:04
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.

1 participant