fix: always show kebab menu in payroll list for consistent alignment#1457
fix: always show kebab menu in payroll list for consistent alignment#1457jeffredodd merged 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR ensures the Payroll list row actions column stays consistently aligned by always rendering the kebab (hamburger) menu for each row, showing a disabled “No actions available” item when no actions apply.
Changes:
- Always render the row kebab menu (including for processed payrolls and other no-action states).
- Add a new i18n string for the disabled empty-actions menu item.
- Update PayrollListPresentation tests to reflect the new always-visible menu behavior.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/types/i18next.d.ts | Adds the new noActionsAvailable key to the PayrollList i18n type definition. |
| src/i18n/en/Payroll.PayrollList.json | Adds the English translation for “No actions available”. |
| src/components/Payroll/PayrollList/PayrollListPresentation.tsx | Renders HamburgerMenu for all rows and falls back to a disabled “No actions available” item when needed. |
| src/components/Payroll/PayrollList/PayrollListPresentation.test.tsx | Updates assertions to expect the menu to be present and to show the disabled fallback item. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <HamburgerMenu | ||
| menuLabel={t('payrollMenuLabel')} | ||
| items={[ | ||
| { | ||
| label: t('noActionsAvailable'), | ||
| onClick: () => {}, | ||
| isDisabled: true, | ||
| }, | ||
| ]} |
There was a problem hiding this comment.
The disabled "No actions available" menu item is defined in multiple places (the processed branch and the default menuItems fallback). Consider extracting a shared noActionsAvailable menu-item definition to avoid duplication and prevent the two instances from drifting over time (label/disabled behavior/etc.).
serikjensen
left a comment
There was a problem hiding this comment.
Flagging this one for additional design work
2e57997 to
eb6267a
Compare
@aaronlee777 you requested to see what it looked like w/o kababs.
|
There was a problem hiding this comment.
🚀 5 New Security Fixes
You just committed 5 security fixes. 😎 Keep up the great work!
🎯 Take a look at what findings you fixed.
| Findings |
|---|
| CWE-918: Server-Side Request Forgery (SSRF) Original Rule ID: rules_lgpl_javascript_ssrf_rule-node-ssrf The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. This rule detected user-controlled URLs being passed to Node.js HTTP client libraries including axios.get(), axios.post(), fetch(), http.get(),http.request(), needle(), request(), urllib.request(),superagent.get(), bent(),... |
| 📘 Learn More |
| CWE-918: Server-Side Request Forgery (SSRF) Original Rule ID: rules_lgpl_javascript_ssrf_rule-node-ssrf The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. This rule detected user-controlled URLs being passed to Node.js HTTP client libraries including axios.get(), axios.post(), fetch(), http.get(),http.request(), needle(), request(), urllib.request(),superagent.get(), bent(),... |
| 📘 Learn More |
| CWE-918: Server-Side Request Forgery (SSRF) Original Rule ID: rules_lgpl_javascript_ssrf_rule-node-ssrf The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. This rule detected user-controlled URLs being passed to Node.js HTTP client libraries including axios.get(), axios.post(), fetch(), http.get(),http.request(), needle(), request(), urllib.request(),superagent.get(), bent(),... |
| 📘 Learn More embedded-react-sdk/sdk-app/vite.config.ts Line 175 in 2e57997 |
| CWE-918: Server-Side Request Forgery (SSRF) Original Rule ID: rules_lgpl_javascript_ssrf_rule-node-ssrf The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. This rule detected user-controlled URLs being passed to Node.js HTTP client libraries including axios.get(), axios.post(), fetch(), http.get(),http.request(), needle(), request(), urllib.request(),superagent.get(), bent(),... |
| 📘 Learn More |
| CWE-918: Server-Side Request Forgery (SSRF) Original Rule ID: rules_lgpl_javascript_ssrf_rule-node-ssrf The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. This rule detected user-controlled URLs being passed to Node.js HTTP client libraries including axios.get(), axios.post(), fetch(), http.get(),http.request(), needle(), request(), urllib.request(),superagent.get(), bent(),... |
| 📘 Learn More |
Scanner: boostsecurity - Semgrep
The kebab menu was conditionally hidden when no actions (skip/delete) were available, causing button misalignment across rows. Now the menu is always rendered with a disabled "No actions available" item when no real actions exist. Made-with: Cursor
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…abled item Replace the disabled "No actions available" menu item with a hidden ButtonIcon placeholder that preserves row alignment. Uses the actual ButtonIcon component via ComponentsContext so the placeholder automatically matches partner overrides. Made-with: Cursor
Extract kebab-eligibility logic into a reusable hasKebabActions helper and conditionally render the placeholder ButtonIcon only when at least one payroll in the list has menu actions. This removes the empty kebab column when no actions are available, giving the table a cleaner layout. Adds a Storybook story to verify the no-kebab-actions case. Made-with: Cursor
7b0f795 to
451eacf
Compare

Summary
Screenshots
Before
After
Test plan
PayrollListWithBlockersStoryandPayrollListWithWireInStatusesStorynow show the kebab icon on every rowMade with Cursor