Skip to content

Linlin fix bio announcement toggle and bio status filter - #5525

Open
linlin-husky wants to merge 25 commits into
developmentfrom
linlin_bio_status_toggle_modal
Open

linlin-husky wants to merge 25 commits into
developmentfrom
linlin_bio_status_toggle_modal

Conversation

@linlin-husky

@linlin-husky linlin-husky commented Sep 10, 2026

Copy link
Copy Markdown

This is a HotFix

Description

This PR restores the Bio Status Filter and Bio Announcement Toggle to the behaviour that ran
unchanged from 2023-07-15 until PR #5261 (merge 93cc4641a, 2026-05-25; the code change
itself is 24e1c6ba2 by Sayali, 2026-05-12), per Jae's request to trace the code back to
when it worked.

Issues Fixed:

  • Bio qualification criteria were silently changed. 24e1c6ba2 replaced
    daysInTeam > 60 (tenure) with weeklySummariesCount >= 8 (weekly output). These are not
    equivalent — someone six months in the team with three summaries qualified under the old
    rule and does not under the new one. The same commit updated the test fixtures
    (daysInTeam: 70weeklySummariesCount: 10), so the suite stayed green and the change in
    business meaning went unnoticed. Restored to the tenure rule.

  • Bio Status Filter returned the wrong people. An intermediate fix replaced the on/off
    toggle with a three-button status selector matching summary.bioPosted === selectedBioStatus
    and dropped the qualification gate entirely. Unqualified users appeared in the list, and
    selecting "Posted" listed people whose workflow was already finished — the opposite of a
    to-do list. Reverted to the on/off toggle with the qualification gate restored.

  • Bio Announcement Toggle. The binary switch could not express the three bio states.
    It is now an inline three-state toggle (posted / default / requested) that saves on change.
    On a qualified user, default and requested both show the yellow banner — both mean
    "still to do" — and posted clears it.

  • Yellow banner and filter did not react to a toggle. state.summaries is local
    component state, so the Redux update dispatched by toggleUserBio never reached the list.
    Only a full refetch — which fired two requests — refreshed it. Setting a user to "Posted"
    now hides the banner and drops them from the filter in the same render, with no refetch.

  • Owners/Administrators saw the highlight intermittently. Two useEffects write
    permissionState on mount and only one carried the Owner/Administrator fallback for
    canSeeBioHighlight and bioEditPermission; whichever async call landed last won.
    Both now apply the same fallbacks.

Fixes:

  • Fixes #[priority high] — Bio Status Filter returning unqualified users and ignoring the
    qualification criteria
  • Fixes #[priority high] — Bio Announcement Toggle not reflecting state changes without a
    manual page reload

Related PRs (if any):

Main changes explained:

  • New src/utils/bioQualification.js — single source of truth for "is this person
    qualified for a bio": totalTangibleHrs > 80 && daysInTeam > 60 && bioPosted !== 'posted'.
    The rule previously existed in three copies with inconsistent field names
    (totalValidWeeklySummaries vs weeklySummariesCount), which is how the yellow bar and the
    filter drifted apart. Covered by src/utils/__tests__/bioQualification.test.js (7 cases
    pinning both thresholds, including one asserting that weeklySummariesCount does not
    participate).

  • WeeklySummariesReport.jsxselectedBioStatus returns to a boolean
    (false = show everyone, true = qualified only), reverting the nullable-enum experiment.
    Filter predicate now calls the shared helper. Added handleBioStatusChange to patch the
    toggled row into state.summaries in place; since that is a dependency of the filtering
    effect, the banner hides and the user leaves the filter in one render. Owner/Administrator
    permission fallbacks applied in both effects that write permissionState.

  • FormattedReport.jsx — yellow banner uses the shared helper. BioSwitch no longer
    triggers a double refetch; it rolls the toggle back when the API rejects the change instead
    of leaving it on a status the server never accepted, and the duplicate success toast is
    removed (toggleUserBio already raises one). Bio editing on dev-admin protected records is
    read-only again (bioCanEdit && !cantEditJaeRelatedRecord), matching the guard already
    applied to team code and summary count.

  • WeeklySummariesToggleFilter.jsx — Bio Status rendered as a single SlideToggle
    alongside Trophies and Over Hours, consistent with the other filters. Removed the
    three-button selector and its optimistic-update machinery. Tooltips now have anchor elements
    (data-for) — previously rendered but never displayed — and their ids are namespaced by
    formId to avoid collisions when several instances mount.

  • SlideToggle.jsx — accepts an optional checked prop. It was uncontrolled, so its
    internal state always started false: loading a saved filter left the switch reading OFF
    while the filter was active, most visibly in FilterPreviewForm. Call sites that pass only
    onChange are unaffected.

  • BioFunction.jsx — migrated to the shared helper; prop renamed
    totalValidWeeklySummariesdaysInTeam.

  • TriStateToggleSwitch.jsx / .module.css — inline three-state toggle moved to CSS
    modules, with clickable hit areas for each state.

  • TriStateToggleSwitch.test.jsx — 6 of 8 tests were failing on this branch. The move to
    CSS modules left the test querying raw class names (.toggle-switch, .knob), which vitest
    stubs as _<key>_<hash>, so every selector returned null. Selectors now resolve through
    the same CSS module the component imports.

  • WeeklySummariesReport.module.css / .module.scss — layout for the bio toggle and the
    filter row: flexible gap spacing, compact padding, fixed min-widths removed so controls size
    naturally.

How to test:

  1. git checkout linlin_bio_status_toggle_modal

  2. npm install && npm start

  3. Clear site data/cache, then log in as an admin user

  4. Navigate to Dashboard → Weekly Summaries Report

  5. Verify qualification. A user qualifies only with > 80 tangible hours,
    > 60 days in team, and a bio status that is not "Posted". Someone below either
    threshold must show no yellow banner and must not appear under the Bio Status
    filter, whatever their toggle is set to.

  6. Verify the Bio Announcement toggle.

    • The toggle moves cleanly between posted (left), default (centre) and
      requested (right).
    • On a qualified user, default and requested both show the yellow banner.
    • Selecting Posted hides the banner immediately, with no page reload.
    • Records for protected accounts (Jae / dev-admin) show read-only status text instead of a
      toggle, unless you are signed in as one of the allow-listed accounts.
  7. Verify the Bio Status filter.

    • Turning Bio Status ON narrows the list to qualified users only.
    • With the filter ON, setting a user to Posted removes them from the list immediately —
      no manual refresh.
    • Load a saved filter that has Bio Status enabled and confirm the switch renders ON
      (it previously showed OFF while the filter was active).
  8. Verify error handling. Block PATCH /userProfile/:id/toggleBio in DevTools, then change
    a status: the toggle should snap back to its previous position rather than resting on an
    unsaved value.

  9. Verify the feature in dark mode.

Screenshots or videos of changes:

Screen.Recording.2026-09-14.at.9.17.02.PM.mov

Note:

  • Filter state shape: selectedBioStatus is a boolean. Note this is local component
    state
    (useState in WeeklySummariesReport), not Redux — it is persisted only when saved
    into a named filter. Saved filters already store it as a boolean (CreateFilterModal /
    UpdateFilterModal default it to false), so existing saved filters stay valid.

  • Scope — files outside WeeklySummariesReport: the dashboard is unaffected, but two areas
    outside the component changed and are worth a look:

    • src/utils/bioQualification.js (new) — shared qualification helper, imported by
      FormattedReport, WeeklySummariesReport and BioFunction.
    • UserProfile/UserProfileEdit/ToggleSwitch/TriStateToggleSwitch.* — the inline toggle
      and its test. The component is also reached through ToggleSwitch switchType="bio", whose
      only other consumer is BioFunction (currently unreferenced), so the practical blast
      radius is the Weekly Summaries bio toggle. Other switchType variants are untouched.
  • Branch kept focused: 46d0ca118 "fix: Improve PeopleReport card element distribution and
    alignment"
    predated the bio work and was unrelated to it, so it has been reverted here
    (78553ab64) and preserved on branch linlin_people_report_card_alignment for its own PR.
    This PR's diff is limited to bio status, the shared qualification helper, and the related
    toggle components.

  • SonarQube: both findings on this PR are resolved in 8d718896a — the nested template
    literal in TriStateToggleSwitch (S4624) and the discarded exception in BioSwitch.

- Add flexbox gap spacing to .reportStats for uniform vertical element distribution (name, role, title, dates)
- Remove fixed heights and implement responsive 'height: 100%' design
- Update ReportBlock.module.css to support consistent flex-based layout
- Add comprehensive English comments explaining layout changes
- Ensure right-side card aligns properly with left-side content

Changes:
- src/components/Reports/PeopleReport/PeopleReport.module.css
- src/components/Reports/sharedComponents/ReportPage/components/ReportBlock/ReportBlock.module.css
- src/components/TeamMemberTasks/style.module.css
- src/components/TeamMemberTasks/TeamMemberTask.jsx
…s Report

- Replace ToggleSwitch component with modal-based bio status selector
- Add 'Set State' button that opens modal with status options (default, requested, posted)
- Display current bio status label next to 'Bio announcement:' heading
- Modal shows all three options as buttons for clear user interaction
- Proper state management: update local state and close modal after selection
- Maintains API refresh functionality after bio status change
- Ensures UI matches Dashboard version with modal-based interaction

This fixes the regression where bio status toggle was hidden or non-functional.
Now users can properly change bio announcement status through the modal interface.
- Change .bioToggle from inline-block to block for proper button display
- Add margin spacing for bioToggle elements
- Remove inline marginTop style from button, rely on CSS class styling
- Change button color from btn-info to btn-primary for better visibility
- Ensure button displays as proper element below bio status label
…ering

- Temporarily always render BioSwitch (remove bioCanEdit check)
- Add console.log to verify component is rendering
- This helps diagnose if issue is permission-based or CSS-based
- Remove debug console.log statement
- Restore bioCanEdit permission check in Bio() function
- Now correctly shows BioSwitch for users with edit permission, BioLabel for read-only
- CSS fixes ensure button displays correctly
- Modal opens when user clicks 'Set State' button
@netlify

netlify Bot commented Sep 10, 2026

Copy link
Copy Markdown

Deploy Preview for highestgoodnetwork-dev ready!

Name Link
🔨 Latest commit 8d71889
🔍 Latest deploy log https://app.netlify.com/projects/highestgoodnetwork-dev/deploys/6aa95b4fa7d48700087e7639
😎 Deploy Preview https://deploy-preview-5525--highestgoodnetwork-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

- Reduce gap between filter buttons from 18px to 10px
- Reduce button padding from 6px 12px to 3px 8px for more compact appearance
- Remove min-width constraint from specialColorsToggleWrap
- Adjust internal gaps for tighter button layout
- Ensure all three bio status filter buttons display on single line
- Add onFocus and onBlur handlers for accessibility
@linlin-husky linlin-husky changed the title Linlin bio status toggle modal Linlin fix bio announcement toggle and bio status filter Sep 11, 2026
- Add comments in handleBioStatusChange explaining toggle behavior
- Add comments on bio status filter button section explaining three filter options
- Add comments on selectedBioStatus destructuring explaining state change from boolean to nullable enum
- Add comments on filter logic explaining simplified bio status matching approach
- These comments document the changes that fix issues with Bio Status Filter displaying identical results
- Implement local state (pendingBioStatus) to immediately show button selection on click
- Buttons now turn blue instantly when clicked, without waiting for Redux state update
- Sync optimistic state with Redux state once update completes via useEffect
- Improves perceived responsiveness and user experience
- Unselected buttons now always keep black text color on hover/focus/blur
- Prevents text from appearing white on light gray background during hover
- Ensures consistent visual appearance across all button states
- Change transition from 'all 0.2s' to 'background-color 0.2s' only
  Prevents color property from being animated and causing flashing
- Remove style.color modifications from event handlers
  Color now always uses inline style definition
- Remove 'color: inherit' from CSS :active state
  Prevents unexpected color inheritance during click
- Add !important to boxShadow in inline style for consistency
- Remove useEffect that was causing unnecessary re-renders and delays
- Use nullish coalescing (??) to prioritize pendingBioStatus over Redux state
- This ensures optimistic UI update is applied immediately without waiting for Redux sync
- Button now turns blue instantly on click without any delay
- Initialize pendingBioStatus with Redux state value instead of null
- Eliminates initial value mismatch that caused delay on first click
- Especially fixes the delay on 'Not requested/posted' button
- Button now responds instantly without any delay
- Add useRef to track internal vs external state changes
- Use useEffect to sync pendingBioStatus when Redux state changes externally
- Prevents state desync that caused delays on subsequent clicks
- Especially fixes delays when clicking 'Not requested/posted' button
- Defer Redux state updates with startTransition when clicking bio status buttons
- Ensures optimistic button color change happens immediately without blocking
- Heavy filterWeeklySummaries operation runs in background at lower priority
- Fixes delays especially on 'Not requested/posted' button when dealing with large datasets
- Improves perceived responsiveness of the button click
- Change unselected button background to #2a2a2a in dark mode (was white)
- Change text color to #ddd for better contrast in dark mode (was black)
- Update border color to #555 in dark mode
- Update hover state background to #3a3a3a for better visibility
- Ensures buttons are clearly visible and readable in dark mode
@one-community one-community added the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Sep 13, 2026
@iAbhi001
iAbhi001 self-requested a review September 13, 2026 04:42
iAbhi001
iAbhi001 previously approved these changes Sep 13, 2026

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

PR Review & Testing Summary

Tested locally on branch linlin_bio_status_toggle_modal against commit a20eb1d. Everything works as expected and aligns with the PR objectives.

Verification Details:

  • Bio Announcement Modal:

  • Clicking Set State opens the modal correctly with all three options (Not requested/posted, Requested, Posted).

  • Selecting a state updates the user card properly (e.g., tested updating status to Requested).

  • Deselection / reverting behavior works as expected.

  • Bio Status Filter Buttons:

  • All three filter buttons render inline on a single row with proper padding and no unwanted wrapping.

  • Filtering by each status correctly narrows down the user list (e.g., selecting Requested filtered the member count accurately down to matching users).

  • Clicking an active filter button deselects it and restores the complete user list.

  • State persists properly across page refresh and navigation.

  • UI & Theming:

  • Dark mode compatibility verified; button borders, backgrounds, and hover/focus states remain readable with no text-color flashing.

Image Image Image

LGTM! Approving.

linlin-husky and others added 8 commits September 13, 2026 20:52
2279697 switched the component to CSS modules but left the test querying
raw class names (.toggle-switch, .knob, .knob-area), which vitest stubs as
_<key>_<hash>. Every selector returned null and 6 of 8 tests failed on this
branch.

Resolve selectors through the same CSS module the component imports, so the
test holds whether or not test.css processing is enabled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Restore the bio workflow to the rules that ran unchanged from 2023-07-15
(14078de) until 24e1c6b (2026-05-12), per Jae's request to trace the
code back to when it worked.

Qualification criteria
  24e1c6b replaced `daysInTeam > 60` with `weeklySummariesCount >= 8`,
  substituting tenure with weekly output — these select different people, and
  it also updated the test fixtures so nothing went red. Restore the tenure
  rule. HGNRest still returns `daysInTeam` (reporthelper.weeklySummaries
  computes it via $dateDiff; formatSummaries passes it through), so only the
  frontend references had been dropped.

  The rule lived in three copies with inconsistent field names
  (totalValidWeeklySummaries vs weeklySummariesCount). Extract it to
  src/utils/bioQualification.js so the yellow bar and the filter cannot drift
  apart again, and cover the thresholds with tests.

Bio Status filter
  Revert the three-button status selector to the on/off toggle. The enum
  version matched `bioPosted === selectedBioStatus` with no qualification
  gate, so unqualified users appeared in the list and selecting "posted"
  listed people whose workflow was already finished.

  SlideToggle was uncontrolled, so a saved filter left the switch reading OFF
  while the filter was active. Give it an optional `checked` prop.

Immediate feedback on toggling
  state.summaries is local component state, so the Redux update dispatched by
  toggleUserBio never reached the list; only a full refetch (which ran two
  requests) refreshed it. Add handleBioStatusChange to patch the row in place
  — it is a dependency of the filtering effect, so the yellow bar hides and
  the user leaves the filter in the same render.

Also
  - Apply the Owner/Administrator permission fallbacks in both effects that
    write permissionState; only one had them, and whichever async call landed
    last won, so admins saw the highlight intermittently.
  - Revert the bio toggle on dev-admin protected records to read-only.
  - Roll the toggle back when the API rejects the change, instead of leaving
    it on a status the server never accepted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reverts 46d0ca1, which predates the bio work on this branch and is
unrelated to it: PeopleReport / ReportBlock / TeamMemberTasks styling.
Keeping it here would add ~96 lines of unrelated CSS to this PR's diff.

Preserved on branch linlin_people_report_card_alignment (da1a059) so the
work is not lost, and can be raised as its own PR.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- TriStateToggleSwitch: extract the inner `bg-${bgColor}` lookup into its own
  variable so the class string is no longer a nested template literal (S4624).
- BioSwitch: the catch rolled the toggle back but discarded the exception.
  Log it and note why nothing further is surfaced — toggleUserBio has already
  toasted the user.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

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

Labels

High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants