Conversation
ServiceNow lets you refresh a single tab; the CSM portal previously required a full page reload to see changed data anywhere. Adds a RefreshButton (icon + "Last refreshed" hint, mirroring the existing dashboard-widget control) to: - Every case detail tab: Activities, Details, Linked Items (+ its three sub-widgets individually), Watchers, Attachments, Time tracking, Call requests. SLA/Tasks are skipped — both are hidden: true in TAB_DEFS and unreachable via the tab bar. - Every list page: Cases/Service Requests/Security Reports/Engagements (via the shared CsmIssuesView), Change Requests, Incidents, Problems, Vulnerabilities, Users, Roles/Groups/Teams (+ their member pages, via the shared DirectoryEntityTable/DirectoryMembersList), Accounts, Projects, Announcements, Updates (post-search results), Time Cards (all three tabs), and the dashboard widget "View more" preview page. Each button wires directly to the underlying React Query hook's own refetch/isFetching/dataUpdatedAt — no new query keys or cross-component cache invalidation, since every hook touched here is a plain useQuery passthrough.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (26)
🚧 Files skipped from review as they are similar to previous changes (18)
📝 WalkthroughWalkthroughThis PR adds manual refresh controls across CSM Portal directory, list, operations, case widget, timecard, and dashboard views. Each control uses query refetch callbacks, fetching state, and last-update timestamps. ChangesRefresh Button Integration
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant LinkedChangeRequestsWidget
participant QueryClient
participant DetailQueries
User->>LinkedChangeRequestsWidget: click RefreshButton
LinkedChangeRequestsWidget->>QueryClient: invalidate linked request queries
QueryClient->>DetailQueries: mark queries stale
DetailQueries-->>LinkedChangeRequestsWidget: update fetching state
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx (1)
34-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftMove
RefreshButtonto a shared UI location.
RefreshButtonis now shared by directory-admin components. Do not keep this shared component undercsm-dashboard.
apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx#L34-L34: importRefreshButtonfrom the new shared location.apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryMembersList.tsx#L40-L40: importRefreshButtonfrom the same shared location.As per coding guidelines, “each
src/features/<name>/owns itsapi/,components/,pages/,types/, andutils/directories.”🤖 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/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx` at line 34, Move the shared RefreshButton component out of csm-dashboard into the appropriate shared UI location, then update imports in apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx lines 34-34 and apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryMembersList.tsx lines 40-40 to use that location.Source: Coding guidelines
apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx (1)
41-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove
RefreshButtonto the shared component layer.
RefreshButtonis now application-wide UI. Do not make unrelated features depend on the dashboard feature. Move it to@components/RefreshButtonand update these imports.
apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx#L41-L41: import the shared component.apps/csm-portal/webapp/src/features/csm-announcements/pages/CsmAnnouncementsPage.tsx#L57-L57: import the shared component.apps/csm-portal/webapp/src/features/csm-projects/pages/CsmProjectsPage.tsx#L36-L36: import the shared component.apps/csm-portal/webapp/src/features/csm-users/pages/CsmUsersPage.tsx#L54-L54: import the shared component.apps/csm-portal/webapp/src/features/updates/pages/CsmUpdatesPage.tsx#L52-L52: import the shared component.apps/csm-portal/webapp/src/features/csm-operations/components/ChangeRequestsTab.tsx#L55-L55: import the shared component.apps/csm-portal/webapp/src/features/csm-operations/components/IncidentsTab.tsx#L56-L56: import the shared component.apps/csm-portal/webapp/src/features/csm-operations/components/ProblemsTab.tsx#L44-L44: import the shared component.apps/csm-portal/webapp/src/features/csm-security-center/components/ProductVulnerabilitiesTab.tsx#L45-L45: import the shared component.As per coding guidelines, each
src/features/<name>/owns itsapi/,components/,pages/,types/, andutils/directories.🤖 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/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx` at line 41, Move the RefreshButton component from the dashboard feature into the shared components layer, preserving its existing behavior and export. Update the imports in apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx:41-41, apps/csm-portal/webapp/src/features/csm-announcements/pages/CsmAnnouncementsPage.tsx:57-57, apps/csm-portal/webapp/src/features/csm-projects/pages/CsmProjectsPage.tsx:36-36, apps/csm-portal/webapp/src/features/csm-users/pages/CsmUsersPage.tsx:54-54, apps/csm-portal/webapp/src/features/updates/pages/CsmUpdatesPage.tsx:52-52, apps/csm-portal/webapp/src/features/csm-operations/components/ChangeRequestsTab.tsx:55-55, apps/csm-portal/webapp/src/features/csm-operations/components/IncidentsTab.tsx:56-56, apps/csm-portal/webapp/src/features/csm-operations/components/ProblemsTab.tsx:44-44, and apps/csm-portal/webapp/src/features/csm-security-center/components/ProductVulnerabilitiesTab.tsx:45-45 to use `@components/RefreshButton`.Source: Coding guidelines
apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx (1)
113-113: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove
RefreshButtonto the shared component layer.The case feature now depends on a dashboard-owned generic control. Move
RefreshButtonto@components, then update these imports.
apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx#L113-L113: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/CallRequestsWidget.tsx#L53-L53: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/CaseDetailWidgets.tsx#L81-L81: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/ChildCasesWidget.tsx#L36-L36: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/CsmIssuesView.tsx#L61-L61: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/LinkedChangeRequestsWidget.tsx#L41-L41: importRefreshButtonfrom the shared component module.apps/csm-portal/webapp/src/features/csm-cases/components/LinkedServiceRequestsWidget.tsx#L40-L40: importRefreshButtonfrom the shared component module.As per coding guidelines, each
src/features/<name>/owns itsapi/,components/,pages/,types/, andutils/directories.🤖 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/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx` at line 113, Move the dashboard-owned RefreshButton component into the shared `@components` layer, then update imports in apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx (line 113), components/CallRequestsWidget.tsx (line 53), components/CaseDetailWidgets.tsx (line 81), components/ChildCasesWidget.tsx (line 36), components/CsmIssuesView.tsx (line 61), components/LinkedChangeRequestsWidget.tsx (line 41), and components/LinkedServiceRequestsWidget.tsx (line 40) to use the shared module; preserve existing RefreshButton usage.Source: Coding guidelines
🤖 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/csm-portal/webapp/src/features/csm-timecards/pages/CsmTimeCardsPage.tsx`:
- Around line 444-450: In CsmTimeCardsPage.tsx, keep each RefreshButton rendered
when its query is in an error state by moving it outside the success-only
conditional or rendering it in both branches: lines 444-450 for myCards, 528-534
for allCards, and 603-609 for queue. Preserve each button’s existing refetch
handler and fetching/update props.
In `@apps/csm-portal/webapp/src/features/updates/pages/CsmUpdatesPage.tsx`:
- Around line 791-809: Update the result action row containing the updates count
and RefreshButton so it renders whenever the search state exists, not only when
sortedEntries.length is greater than zero. Preserve the existing count text and
RefreshButton behavior, including refetch, fetching state, timestamp, and label,
for both populated and empty search results.
---
Nitpick comments:
In `@apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx`:
- Line 41: Move the RefreshButton component from the dashboard feature into the
shared components layer, preserving its existing behavior and export. Update the
imports in
apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsx:41-41,
apps/csm-portal/webapp/src/features/csm-announcements/pages/CsmAnnouncementsPage.tsx:57-57,
apps/csm-portal/webapp/src/features/csm-projects/pages/CsmProjectsPage.tsx:36-36,
apps/csm-portal/webapp/src/features/csm-users/pages/CsmUsersPage.tsx:54-54,
apps/csm-portal/webapp/src/features/updates/pages/CsmUpdatesPage.tsx:52-52,
apps/csm-portal/webapp/src/features/csm-operations/components/ChangeRequestsTab.tsx:55-55,
apps/csm-portal/webapp/src/features/csm-operations/components/IncidentsTab.tsx:56-56,
apps/csm-portal/webapp/src/features/csm-operations/components/ProblemsTab.tsx:44-44,
and
apps/csm-portal/webapp/src/features/csm-security-center/components/ProductVulnerabilitiesTab.tsx:45-45
to use `@components/RefreshButton`.
In
`@apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx`:
- Line 34: Move the shared RefreshButton component out of csm-dashboard into the
appropriate shared UI location, then update imports in
apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsx
lines 34-34 and
apps/csm-portal/webapp/src/features/csm-admin/components/DirectoryMembersList.tsx
lines 40-40 to use that location.
In `@apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx`:
- Line 113: Move the dashboard-owned RefreshButton component into the shared
`@components` layer, then update imports in
apps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsx (line
113), components/CallRequestsWidget.tsx (line 53),
components/CaseDetailWidgets.tsx (line 81), components/ChildCasesWidget.tsx
(line 36), components/CsmIssuesView.tsx (line 61),
components/LinkedChangeRequestsWidget.tsx (line 41), and
components/LinkedServiceRequestsWidget.tsx (line 40) to use the shared module;
preserve existing RefreshButton usage.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 28150233-5740-4d5f-90bf-b463f99bf305
📒 Files selected for processing (24)
apps/csm-portal/webapp/src/features/csm-accounts/pages/CsmAccountsPage.tsxapps/csm-portal/webapp/src/features/csm-admin/components/DirectoryEntityTable.tsxapps/csm-portal/webapp/src/features/csm-admin/components/DirectoryMembersList.tsxapps/csm-portal/webapp/src/features/csm-admin/pages/CsmGroupsPage.tsxapps/csm-portal/webapp/src/features/csm-admin/pages/CsmRolesPage.tsxapps/csm-portal/webapp/src/features/csm-admin/pages/CsmTeamsPage.tsxapps/csm-portal/webapp/src/features/csm-announcements/pages/CsmAnnouncementsPage.tsxapps/csm-portal/webapp/src/features/csm-cases/components/CallRequestsWidget.tsxapps/csm-portal/webapp/src/features/csm-cases/components/CaseDetailWidgets.tsxapps/csm-portal/webapp/src/features/csm-cases/components/ChildCasesWidget.tsxapps/csm-portal/webapp/src/features/csm-cases/components/CsmIssuesView.tsxapps/csm-portal/webapp/src/features/csm-cases/components/LinkedChangeRequestsWidget.tsxapps/csm-portal/webapp/src/features/csm-cases/components/LinkedServiceRequestsWidget.tsxapps/csm-portal/webapp/src/features/csm-cases/pages/CsmCaseDetailPage.tsxapps/csm-portal/webapp/src/features/csm-dashboard/pages/DashboardWidgetPreviewPage.tsxapps/csm-portal/webapp/src/features/csm-operations/components/ChangeRequestsTab.tsxapps/csm-portal/webapp/src/features/csm-operations/components/IncidentsTab.tsxapps/csm-portal/webapp/src/features/csm-operations/components/ProblemsTab.tsxapps/csm-portal/webapp/src/features/csm-projects/pages/CsmProjectsPage.tsxapps/csm-portal/webapp/src/features/csm-security-center/components/ProductVulnerabilitiesTab.tsxapps/csm-portal/webapp/src/features/csm-timecards/components/CaseTimeCardsPanel.tsxapps/csm-portal/webapp/src/features/csm-timecards/pages/CsmTimeCardsPage.tsxapps/csm-portal/webapp/src/features/csm-users/pages/CsmUsersPage.tsxapps/csm-portal/webapp/src/features/updates/pages/CsmUpdatesPage.tsx
Two real bugs, both about a RefreshButton disappearing exactly when it's most needed: - CsmTimeCardsPage.tsx (all three tabs): the button lived inside the success-only branch, so a load error hid it along with the table/export/ pagination — no way to retry without reloading the page. Moved it above the isError branch so it's always available; kept the export button gated on !isError since there's nothing valid to export during one. - CsmUpdatesPage.tsx: same issue for a zero-result search — the button only rendered in the has-results branch. Hoisted it to the top of the results section so it shows across loading/error/empty/populated states. Also addressed the recurring nitpick: RefreshButton was dashboard-owned (`@features/csm-dashboard/components/RefreshButton`) but reused across ten unrelated features by the PR this addresses, violating this repo's feature-boundary convention. Moved it to `@components/RefreshButton` (shared layer, alongside QueryErrorState/SeverityChip/etc.) and repointed all 24 import sites, including the four pre-existing dashboard-widget consumers. No behavior change to the component itself.
|
Addressed the recurring nitpick about |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Purpose
ServiceNow lets you refresh an individual tab within a case's details. In the CSM portal
webapp, seeing changed data anywhere — a case detail tab, or any searchable list page —
required a full page reload. There was no way to just re-pull one tab's or one list's data.
Goals
Add a refresh control everywhere a tab or page shows live, potentially-stale query data, so
a user can pull fresh data in place instead of reloading the whole page.
Approach
Reused the existing
RefreshButtoncomponent (icon button + "Last refreshed X ago" hint),already used on the dashboard's widget cards — same look and behavior everywhere now.
Every button wires directly to the underlying React Query hook's own
refetch/isFetching/dataUpdatedAt. No new query keys, no cross-component cacheinvalidation — every hook touched here is a plain
useQuerypassthrough, so this is additivewiring, not a data-layer change.
Case detail page (
CsmCaseDetailPage.tsx) — every tab:linked chat, attachments, call requests).
the three sub-widgets (Child cases, Linked service requests, Linked change requests) got its
own button for its own enrichment query.
hidden: trueinTAB_DEFSandunreachable from the tab bar in this build.
List pages — one button per page/tab, wired to that page's search hook:
share
CsmIssuesView, so one change covers all four.has its own tab component.
DirectoryEntityTable; their member pages shareDirectoryMembersList— one change each covers three pages.live list) — reruns the same search.
User stories
As a CS engineer, I can refresh a single case-detail tab or list page in place, without
reloading the whole app and losing my scroll position/filters/open dialogs.
Release note
Case detail tabs and list pages across the CSM portal now have a refresh button, so you no
longer need to reload the page to see updated data.
Documentation
N/A — no published documentation covers this internal UI behavior.
Training
N/A.
Certification
N/A.
Marketing
N/A.
Automation tests
hooks; no new query/business logic to unit test.
tsc -bandeslintclean on every touchedfile. The existing
vitestsuites for these features were re-run (csm-cases,csm-admin,csm-operations,csm-security-center,csm-accounts,csm-projects,csm-announcements,updates,csm-timecards,csm-users,csm-dashboard): the onlyfailures are 6 pre-existing ones (
CsmRolesPage.test.tsx,CsmAnnouncementsPage.test.tsx),confirmed via
git stashto fail identically without this change.vite buildclean.verified in a browser — I don't have a live backend/Asgardeo session in this environment,
so only the type-check/lint/test/build gates are confirmed, not an actual click-through.
Security checks
Samples
N/A
Related PRs
None.
Migrations (if applicable)
N/A — no schema or data change, UI-only.
Test environment
./node_modules/.bin/*directly — thepnpmCLI itself errors with"packages field missing or empty" in this environment).
tsc -b,eslint,vitest,vite build— all clean as noted above.Learning
N/A.
Summary by CodeRabbit