Skip to content

Purav Finish PR #2052 Centralize permission keys for hasPermission - #5431

Merged
one-community merged 17 commits into
developmentfrom
feature/Purav-takingover-permission-constants
Sep 13, 2026
Merged

one-community merged 17 commits into
developmentfrom
feature/Purav-takingover-permission-constants

Conversation

@pixelpix13

@pixelpix13 pixelpix13 commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Description

Implements permission-key constants so components no longer pass raw strings into hasPermission() (PR #2052 / task: Finish PR2052 – Create constants for permission keys).
pr 5431 task

This is a frontend refactor only (takeover of Anirudh’s WIP Anirudh_permissionsMangement). There is no new UI feature. Runtime permission values are unchanged (permissions.postProject === 'postProject'), so behavior should match development when the same permissions are assigned.

Motivation: Reused hardcoded strings across many components are typo-prone and hard to maintain. Centralizing keys in permissionKeys.js (sourced from Permissions.json + legacy keys) and using RoutePermissions in Header improves consistency and maintainability going forward (per Jae/Diego notes on PR #2052).

Fixes / Implements: PR #2052 (PRIORITY LOW – Finish constants for permission keys / WIP Purav #2052)

Related PRS (if any):

  • Frontend-only PR — no related backend PR.
  • Takeover / continuation of Anirudh’s earlier WIP branch Anirudh_permissionsMangement (never merged); reimplemented on current development with flat permissions.* keys + RoutePermissions (instead of nested hand-written constants).

Main changes explained:

  • Create src/utils/permissionKeys.js — builds frozen permissions map from Permissions.json + LEGACY_OR_EXTRA_KEYS; also exports permissionCategories.
  • Update src/utils/constants.js — re-exports permissions / permissionCategories.
  • Update src/utils/routePermissions.js — route/nav permission lists use permissions.* constants.
  • Update src/utils/permissions.js — supports array-style OR checks used by RoutePermissions.
  • Update Header and many feature areas (User Management, Projects/WBS, Teams, Timelog, Badges, Warnings, Permissions Management, BM/CP/KI headers, Weekly Summaries Report, Job Analytics, etc.) to call hasPermission(permissions.X) / RoutePermissions.* instead of string literals.
  • Update leftover access checks (viewWBSpermissionsRequired, routes Blue Square Email, frontPermissions.includes(...), etc.) to use the same constants.
  • Synced with latest origin/development (Header / UserManagement conflicts resolved while keeping constants).
Before After
hasPermission('postProject') hasPermission(permissions.postProject)
Long Header OR-chains of strings hasPermission(RoutePermissions.userManagement) etc.
Scattered magic strings Central map in permissionKeys.js

How to test:

  1. Check out this branch: feature/Purav-takingover-permission-constants
  2. Run npm install (Node v20.19.4 recommended), then start locally: npm run start:local (app at http://localhost:5173)
  3. Clear site data/cache for localhost if needed
  4. Log in as Admin (and also retest as Volunteer). For full role CRUD / permission toggles, use an Owner account (or ask Jae to upgrade a Dev account)

Smoke (Admin / Volunteer)

  • App loads with no console/runtime errors from permission checks
  • Header nav shows expected links for that role (Reports, User Management, Projects, Teams, Badges, Permissions Management, Send Emails, Schedule Meetings, etc.)
  • Permissions Management page opens
  • Dark mode still works normally (no UI redesign in this PR — confirm existing screens look correct in dark mode)

Permission ON / OFF regression (Owner recommended)

Toggle permissions in Permissions Management → Save → hard refresh / re-login → confirm UI:

  • Header / nav — Reports, Weekly Summaries, User Management, Badge Management, Projects, Teams, Permissions Management, Announcements/Send Emails, Schedule Meetings, PR Dashboard, Blue Square Email Management
  • User Management — list / create / delete user, status/pause, time-off, set final day
  • Projects / WBS / Tasks — project CRUD, members, WBS, tasks
  • Teams — create/edit/delete, assign members
  • Timelog / Weekly Summaries — edit/delete entries, edit summaries
  • Badges / Blue Squares / Warnings
  • Other — LeaderBoard, SummaryBar, Job Analytics (getJobReports), Weekly Summaries bio highlight filter

Pass criteria: ON → control available and works; OFF → hidden/disabled/blocked; no white screens.

Known note to verify

  • Header Badge Management uses RoutePermissions.badgeManagement, which includes assignBadges (development Header OR-chain did not). Confirm whether users with only Assign Badges should see that nav item.

Screenshots or videos of changes:

pr 5431_1 pr 5431_2
pr.5431_video.mp4

Note:

  • No new UI/feature — reviewers should verify behavior parity with development, not look for new screens.
  • Full permission regression needs Owner (or postRole / putRole / deleteRole). Admin alone may not be able to add/edit/delete roles.
  • Dark mode: unchanged by design; still confirm no regressions on touched pages.
  • CSS: no new generic global class names introduced for this refactor.
  • Quality Gate / SonarCloud: passed on latest analysis after cleanup commits.

pixelpix13 and others added 4 commits August 3, 2026 21:24
…le components for improved maintainability and consistency. Updated permission checks in BMHeader, BadgeDevelopmentTable, BadgeReport, JobFormBuilder, CPHeader, Header, EnhancedJobFormBuilder, and various Project components.
…stants

Co-authored-by: Cursor <cursoragent@cursor.com>
…stants

Co-authored-by: Cursor <cursoragent@cursor.com>
…nstants.

Co-authored-by: Cursor <cursoragent@cursor.com>
@netlify

netlify Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for highestgoodnetwork-dev ready!

Name Link
🔨 Latest commit 225483b
🔍 Latest deploy log https://app.netlify.com/projects/highestgoodnetwork-dev/deploys/6aa4d2b68b63af0008cc237d
😎 Deploy Preview https://deploy-preview-5431--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.

…rmission vars, add sort comparator.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pixelpix13 pixelpix13 changed the title Finish PR #2052: Centralize permission keys via permissionKeys constants Purarv-Takingover-PR #2052: Centralize permission keys via permissionKeys constants Aug 6, 2026
@pixelpix13 pixelpix13 changed the title Purarv-Takingover-PR #2052: Centralize permission keys via permissionKeys constants Purav-Takingover-PR #2052: Centralize permission keys via permissionKeys constants Aug 6, 2026
@pixelpix13 pixelpix13 changed the title Purav-Takingover-PR #2052: Centralize permission keys via permissionKeys constants Purav Finish PR #2052 Centralize permission keys for hasPermission Aug 9, 2026
@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 Aug 13, 2026

@Adit0717 Adit0717 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tested this locally on the "feature/Purav-takingover-permission-constants" branch. Verified the following routes using both Admin and Volunteer roles:

Admin role:

/projects - accessible
/usermanagement - accessible
/badgemanagement - accessible
/teams - accessible
/permissionsmanagement - accessible
/announcements - redirected to /dashboard

Volunteer role:

/projects, /usermanagement, /badgemanagement, /teams, /permissionsmanagement - all redirected to /dashboard

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

I see after toggle on/off the persmission management table is not updated, it is intended behavior?
Admin:

Image Image Image Image Image Image Image

Toggle Permission
Image
Image
Image
Assign badge is toggled off and assign badge is enabled and it allows to select badges and on clicking confirm it throws below error. The message should state no permission/permission toggled off something like that.
Image
Create team is not available as its toggled off
Image
JobAnalytic:
Image
Image
Image
Image
Image

Volunteer:

Image Image Image Image

@nathanah nathanah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think 'update:badges' is the wrong key.
I caught some redundant role checks for owner that we can clean up while we're at it.
Could reorganize the groups to be more useful, but this is fine.
Otherwise, looks good.

Comment on lines +30 to +31
const canUpdateBadges = hasPermission(permissions['update:badges']);
const canDeleteBadges = hasPermission(permissions['delete:badges']);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
const canUpdateBadges = hasPermission(permissions['update:badges']);
const canDeleteBadges = hasPermission(permissions['delete:badges']);
const canUpdateBadges = hasPermission(permissions.updateBadges);
const canDeleteBadges = hasPermission(permissions.deleteBadges);

Should it be this?


const canDeleteQuestionSets = useMemo(
() => userRole === 'Owner' || dispatch(hasPermission('deleteFormQuestions')),
() => userRole === 'Owner' || dispatch(hasPermission(permissions.deleteFormQuestions)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
() => userRole === 'Owner' || dispatch(hasPermission(permissions.deleteFormQuestions)),
() => dispatch(hasPermission(permissions.deleteFormQuestions)),


const canEditQuestionSets = useMemo(
() => userRole === 'Owner' || dispatch(hasPermission('editFormQuestions')),
() => userRole === 'Owner' || dispatch(hasPermission(permissions.editFormQuestions)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
() => userRole === 'Owner' || dispatch(hasPermission(permissions.editFormQuestions)),
() => dispatch(hasPermission(permissions.editFormQuestions)),


const canCreateQuestionSets = useMemo(
() => userRole === 'Owner' || dispatch(hasPermission('createFormQuestions')),
() => userRole === 'Owner' || dispatch(hasPermission(permissions.createFormQuestions)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
() => userRole === 'Owner' || dispatch(hasPermission(permissions.createFormQuestions)),
() => dispatch(hasPermission(permissions.createFormQuestions)),


const canCreateQuestionSets = useMemo(
() => userRole === 'Owner' || dispatch(hasPermission('createFormQuestions')),
() => userRole === 'Owner' || dispatch(hasPermission(permissions.createFormQuestions)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
() => userRole === 'Owner' || dispatch(hasPermission(permissions.createFormQuestions)),
() => dispatch(hasPermission(permissions.createFormQuestions)),


const canManageForms = useMemo(
() => userRole === 'Owner' || dispatch(hasPermission('manageJobForms')),
() => userRole === 'Owner' || dispatch(hasPermission(permissions.manageJobForms)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
() => userRole === 'Owner' || dispatch(hasPermission(permissions.manageJobForms)),
() => dispatch(hasPermission(permissions.manageJobForms)),

Comment thread src/components/Header/Header.jsx Outdated
Comment on lines +214 to +215
props.hasPermission(RoutePermissions.permissionsManagement, !isAuthUser) ||
props.hasPermission(RoutePermissions.userPermissionsManagement, !isAuthUser);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
props.hasPermission(RoutePermissions.permissionsManagement, !isAuthUser) ||
props.hasPermission(RoutePermissions.userPermissionsManagement, !isAuthUser);
props.hasPermission(RoutePermissions.permissionsManagement, !isAuthUser);

pixelpix13 and others added 2 commits August 17, 2026 15:07
…checks, simplify Header permissionsManagement access.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pixelpix13

Copy link
Copy Markdown
Contributor Author

@DeepighaJ can you tell me what role did you use to test?

…on-only access pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>

@linlin-husky linlin-husky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I tried to login with Volunteer and admin Role: for both roles, Route protection works as expected. Directly navigating to admin routes (/projects, /usermanagement, /badgemanagement, /teams, /permissionsmanagement) correctly redirects back to /dashboard. Also for admin role, Core management pages and header navigation load properly with the updated permission constants.

However, when I navigated to check Badge Management, when I clicked the Edit button in badge management, the page crashed.

Attaching the crash screenshot. Could you please take a look at the modal trigger and permission checks in BadgeDevelopmentTable.jsx?

Image Image

Use props.hasPermission in BadgeDevelopmentTable and null-safe badge field loading in EditBadgePopup so null API values no longer throw on .length.

Co-authored-by: Cursor <cursoragent@cursor.com>

@linlin-husky linlin-husky left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review Summary & Regression Findings

Tested locally on the latest commit d3e6750 (feature/Purav-takingover-permission-constants).

While the previous white-screen crash on clicking "Edit" is resolved, two blocking functional issues were identified during testing:


1. Badge Management: Edits fail to update/persist

  • Steps to Reproduce:
    1. Go to Badge Management -> Badge Development.
    2. Click Edit on any badge (e.g., "0 Hours for 6 Week Streak").
    3. Modify any field (Name, Description, Type, etc.) in the Edit Badge popup and click Update.
  • Issue: The modal closes/submits, but the changes do not persist or reflect in the table.
    pls check the below two images
Image Image

Because I just got the owner access from jae, so i get to check in owner role

2. Permissions Management: when logging in as owner User permissions are non-interactive

  • Steps to Reproduce:
    1. Go to Permissions Management -> Manage User Permissions.
    2. Select any active user
  • Issue: All action buttons (Delete / Toggle) on the right side are permanently disabled/grayed out, and clicking the permissions produces no state updates.
  • Note: Please check PermissionList.jsx, PermissionListItem.jsx, and PermissionsConst.js for key mismatch issues with the refactored constants.
Screenshot 2026-08-20 at 12 24 31 PM

Thank you!

@DeMoliT1on DeMoliT1on left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Apart from single suggestion rest looks good to me

import EditBadgePopup from './EditBadgePopup';
import DeleteBadgePopup from './DeleteBadgePopup';
import hasPermission from '../../utils/permissions';
import { permissions } from '../../utils/constants';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { permissions } from '../../utils/constants';
import { permissions } from '~/utils/constants';

I would encourage you to use absolute imports rather than relative ones wherever possible, this would make them much more readable

@nathanah nathanah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One more small change, then I'll approve.

Comment thread src/components/Badge/BadgeManagement.jsx Outdated
Comment thread src/components/Badge/BadgeManagement.jsx Outdated
Comment thread src/components/Badge/BadgeManagement.jsx
Comment thread src/components/Badge/BadgeManagement.jsx
Co-authored-by: Nathan Hoffman <nathanahoffman@gmail.com>
nathanah
nathanah previously approved these changes Aug 21, 2026
…tor.

Gate Select Featured on updateBadges and modifyBadgeAmount permissions per Nathan review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>

@linlin-husky linlin-husky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I rereviewed the edit badge functionality, I found the update button is disabled. could you pls check?

Image

nathanah
nathanah previously approved these changes Aug 23, 2026

@DeMoliT1on DeMoliT1on left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tested again on local for frontend PR changes branch feature/Purav-takingover-permission-constants with related backend PR and observed the following things.


Issue 1 – "Create New Badge" action missing frontend permission check

Observed:

  • Logged in using a user who only has "See Badges" permission and navigate to Badge Management page
  • The "Create New Badge" button remains clickable even if the logged-in user lacks badge creation permissions.
  • Clicking the button allows the user to open the "New Badge" modal and submit the form, which only fails after triggering an authorization error from the backend API ("You are not authorized to create new badges.").

Expected Behavior

  • The "Create New Badge" button should be disabled on the frontend using hasPermission(permissions.createBadges) if the user does not possess the requisite permission.

Screenshots

Image Image Image

Overall Assessment

Verified Working

  • Permission Constants Implementation: Replaced hardcoded permission string literals across components (Header, User Management, Projects/WBS, Teams, Timelog, Badges, Permissions Management, etc.) with centralized permissions.* constants exported from permissionKeys.js.
  • Route Permissions & Checks: Updated routePermissions.js and hasPermission() utility functions to support array-style checks seamlessly.
  • Header Navigation Parity: Verified Header links (User Management, Reports, Projects, Teams, Badges, Permissions Management, etc.) render as expected based on assigned user role permissions without runtime console errors.
  • Permission Toggle Functionality: Tested turning permissions ON and OFF for role configurations in Permissions Management - UI controls correctly show/hide/disable based on updated constant-based permission checks.
  • Dark Mode Parity: Confirmed existing UI layout and theme display remain intact with no styling regressions in dark mode across updated pages.

Requesting Changes

Please address the missing frontend permission check on the "Create New Badge" button before merging:

  • "Create New Badge" button should use hasPermission(permissions.createBadges) so unauthorized users cannot invoke the modal or submit the request.

Resolve routePermissions conflict using permissions.* constants including
rescheduleEvent. Gate Create New Badge with createBadges permission and fix
Edit Badge form sync so Update enables when badge data loads correctly.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pixelpix13

Copy link
Copy Markdown
Contributor Author

I rereviewed the edit badge functionality, I found the update button is disabled. could you pls check?

Image

Hey @linlin-husky, I think it's because the image URL field is empty

@sonarqubecloud

sonarqubecloud Bot commented Sep 3, 2026

Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

Co-authored-by: Cursor <cursoragent@cursor.com>
MahalakshmiPFW
MahalakshmiPFW previously approved these changes Sep 5, 2026

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

Hi! Everything was tested locally and seems to be working fine. Admin and Volunteer route permissions are behaving as expected.

nathanah
nathanah previously approved these changes Sep 6, 2026
muthapriyanka
muthapriyanka previously approved these changes Sep 9, 2026

@muthapriyanka muthapriyanka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tested PR https://github.com/OneCommunityGlobal/HighestGoodNetworkApp/pull/5431locally.
Updated some permissions and badge creation.
One suggestion is the permission management page has a grid around it which is hardly visible in dark mode may be in future PR we can improve that.
Image
Image
Image
Image

shubhamjakhete
shubhamjakhete previously approved these changes Sep 10, 2026

@shubhamjakhete shubhamjakhete left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi,

I checked the key mapping mechanically rather than only by clicking through the UI.

All constants resolve. Every permission key referenced on this branch checks out against Permissions.json or LEGACY_OR_EXTRA_KEYS. Nothing evaluates to undefined, which would deny silently with no error.

One behaviour change worth noting. development uses hasPermission('update:badges') at BadgeDevelopmentTable.jsx:30, and neither update:badges nor delete:badges exists in Permissions.json, so those checks have never returned true for anyone. updateBadges and deleteBadges do exist, making the switch a real fix rather than a rename. Badge update and delete controls will start appearing for users who have never seen them. Worth updating the description, since "runtime permission values are unchanged" isn't quite accurate here.

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

Hi @pixelpix13
Tested the pr #5431 locally as admin
App loads successfully
Header loads as intended all the links works

Image Image Image Image Image Image

just you can look into font and color , apart from that everything works as intended

Resolve EditBadgePopup conflict by keeping null-safe edit loading plus missing-field warning, and extend permissions management route access using RoutePermissions constants.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove unused userRole in JobFormbuilder and use RegExp.exec in badge error parsing.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

Copy link
Copy Markdown

@one-community

Copy link
Copy Markdown
Member

Thank you all, merging!

@one-community
one-community merged commit 519e05d into development Sep 13, 2026
10 checks passed
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.