Skip to content

feat(csm-timecards): searchable filters, minutes not hours, tighter approver gating - #1055

Merged
rksk merged 3 commits into
wso2-open-operations:dev-app-csm-portalfrom
Hesara2003:feature/timecards-filter-dropdowns
Jul 6, 2026
Merged

rksk merged 3 commits into
wso2-open-operations:dev-app-csm-portalfrom
Hesara2003:feature/timecards-filter-dropdowns

Conversation

@Hesara2003

@Hesara2003 Hesara2003 commented Jul 6, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.

Follow-up usability and correctness fixes on top of #1028, found while continuing to exercise the time-cards feature: unwieldy free-text/plain-select filters, a real hours/minutes unit mismatch (the backend stores minutes; the form collected and displayed hours without converting), and two approver-gating gaps. No tracked issue number for this batch.

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

  • Replace the Work item / Engineer / Project filters with a searchable multi-select, matching the pattern already used on the Cases page's Assignee filter.
  • Fix logged time being recorded at 1/60th of the real value — the backend's time fields are minutes (confirmed: its own validation helper is named nonNegativeMinutes), not hours.
  • Restrict the Approvals tab and approve/reject actions to the dedicated approver group only — generic portal admins no longer get it automatically.
  • Remove a "Category" field from the Log time dialog that was never actually sent to the backend.
  • Stop showing a "Review" button on your own submitted time cards — deciding your own card always 403s, so the button was unusable there.

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

  • Extracted MultiSelectField and SearchableMultiSelect out of CasesFilterBar.tsx into shared components under src/components/ so csm-timecards (and any future feature) can reuse the same look/behavior instead of duplicating it. CasesFilterBar.tsx now imports from there too — no behavior change for Cases.
  • Work item, Engineer, and Project filters on /time-cards are now searchable multi-selects, sourced from whatever's already loaded on the current tab/page (no new API calls introduced).
  • Renamed CsmTimeCard.totalHours / CsmTimeSheet.totalHours to totalMinutes and made minutes the native unit end-to-end: usePostTimeCard no longer converts (form collects whole minutes directly), mapTimeCard no longer converts (direct passthrough), and every display (Log time dialog, case Time tracking panel, weekly sheet cards, review dialog) shows minutes.
  • useTimecardRole()'s isApprover now reflects only the dedicated sn_customerservice_timecard_approver group; isAdmin is tracked independently and no longer folded in.
  • CaseTimeCardsPanel's Review button now checks card.userId !== signed-in user.id before rendering.

No screenshot yet — happy to add one or demo live if useful before merge.

User stories

Summary of user stories addressed by this change

  • As an engineer, I can filter my time sheets/cases by work item, project, or engineer by typing instead of scrolling a long list or typing an exact match.
  • As an engineer, the hours I log actually get recorded as that many hours, not a fraction of a minute's worth.
  • As a designated time-card approver, I only see cards I'm actually eligible to decide, and I'm not shown a dead-end "Review" button on my own submissions.

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Time-card filters (work item, engineer, project) are now searchable; logged time is now correctly tracked and displayed in minutes; the Approvals tab is now limited to designated time-card approvers.

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

N/A — internal CSM portal UI, no external product documentation covers this feature.

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

N/A — not training content.

Certification

Type “Sent” when you have provided new/updated certification questions...

N/A — no certification exam impact.

Marketing

Link to drafts of marketing content...

N/A — internal tooling, not customer-facing marketing content.

Automation tests

  • Unit tests

    Code coverage information

    pnpm run test — 128 tests pass, including rewritten/new coverage for the minutes conversion (timeCardTotals.test.ts) and sheet grouping (timeSheetGrouping.test.ts).

  • Integration tests

    Details about the test cases and coverage

    Local Playwright E2E suite updated for the new searchable Work item filter (TimeCardsPage.ts, my-sheets.spec.ts, approvals.spec.ts); full live run pending a fresh captured staging session.

Security checks

Samples

Provide high-level details about the samples related to this feature

N/A

Related PRs

List any other related PRs

Branches off #1028 (merged into dev-app-csm-portal).

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

N/A — no data migration. Time cards were already stored in minutes server-side; this only fixes how the frontend collects/displays that value, going forward.

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Local dev server (pnpm run dev), macOS, Chromium via Playwright, real staging backend (ServiceNow-backed entity-service).

Learning

Describe the research phase...

Confirmed the hours/minutes unit mismatch by cross-referencing entity-service's nonNegativeMinutes validation helper name against a real pre-existing card's totalTime value, which only made sense as minutes.

Summary by CodeRabbit

  • New Features

    • Introduced reusable multi-select controls, including a searchable multi-select, now used in time-card filtering.
    • Enhanced time-card filters with multi-select project/work-item/engineer selection, plus improved “filter work item” and “clear all” behaviors.
  • Bug Fixes

    • Time tracking now consistently uses whole minutes across the time cards experience (display, validation, totals).
    • Improved “Review” action visibility based on role and ownership.
    • Removed the “Category” field from the time entry form.

…tighter approver gating

Work item, engineer, and project filters now use a shared searchable
multi-select instead of plain text/select fields. Time is tracked and
shown in whole minutes everywhere, matching what the backend actually
stores. Approvals tab is restricted to the real approver group instead
of also granting it to generic admins. Removed the dead Category field
from Log time (never sent to the backend). Fixed the Review button
showing on your own submitted cards even though deciding your own card
always 403s.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c767ffce-e38d-4bfb-8458-1d71c7e3c4ce

📥 Commits

Reviewing files that changed from the base of the PR and between ff8a7b4 and 1dc781b.

📒 Files selected for processing (4)
  • apps/csm-portal/webapp/src/components/MultiSelectField.tsx
  • apps/csm-portal/webapp/src/components/SearchableMultiSelect.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/CasesFilterBar.tsx
  • apps/csm-portal/webapp/tests/e2e/specs/timecards/my-sheets.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/csm-portal/webapp/tests/e2e/specs/timecards/my-sheets.spec.ts
  • apps/csm-portal/webapp/src/components/SearchableMultiSelect.tsx

📝 Walkthrough

Walkthrough

This PR adds shared multi-select components, refactors cases filters to use them, and migrates timecard totals, validation, display, and filtering from hours to minutes. It also removes the timecard Category field, updates role checks, and adjusts e2e coverage for the new filter controls.

Changes

Shared multi-select components

Layer / File(s) Summary
Multi-select components
apps/csm-portal/webapp/src/components/MultiSelectField.tsx, apps/csm-portal/webapp/src/components/SearchableMultiSelect.tsx
Adds shared fixed-option and searchable multi-select inputs backed by oxygen-ui Autocomplete, with exported prop interfaces and checkbox/chip rendering.
CasesFilterBar wiring
apps/csm-portal/webapp/src/features/csm-cases/components/CasesFilterBar.tsx
Removes the local multi-select implementation and imports the shared MultiSelectField instead.

Timecard minute migration

Layer / File(s) Summary
Timecard contracts and constants
apps/csm-portal/webapp/src/features/csm-timecards/types/timeCards.ts, apps/csm-portal/webapp/src/features/csm-timecards/constants/timeCardConstants.ts
Renames totals to totalMinutes, removes TimeCardCategory, and drops category constants.
Totals and grouping utilities
apps/csm-portal/webapp/src/features/csm-timecards/utils/timeCardTotals.ts, apps/csm-portal/webapp/src/features/csm-timecards/utils/timeSheetGrouping.ts, apps/csm-portal/webapp/src/features/csm-timecards/utils/__tests__/*
Replaces hour-based helpers and validation with minute-based logic and updates the related tests.
Timecard API mapping
apps/csm-portal/webapp/src/features/csm-timecards/api/useTimeCards.ts, apps/csm-portal/webapp/src/features/csm-timecards/api/useTimeSheets.ts
Updates documentation and mapping so backend totals populate totalMinutes.
Log time dialog
apps/csm-portal/webapp/src/features/csm-timecards/components/LogTimeCardDialog.tsx
Switches the dialog to minute-based entry, removes Category state/UI/payload, and updates validation and touched tracking.
Minute-based displays
apps/csm-portal/webapp/src/features/csm-timecards/components/CaseTimeCardsPanel.tsx, apps/csm-portal/webapp/src/features/csm-timecards/components/TimeCardReviewDialog.tsx, apps/csm-portal/webapp/src/features/csm-timecards/components/TimeSheetCard.tsx
Displays totals in minutes and adds current-engineer-based review visibility in the case panel.
Role logic
apps/csm-portal/webapp/src/features/csm-timecards/hooks/useTimecardRole.ts, apps/csm-portal/webapp/src/features/csm-timecards/hooks/useIsTeamLead.ts
Makes approver and admin membership independent in the timecard role hook and updates the related hook docs.
Timecards page filters
apps/csm-portal/webapp/src/features/csm-timecards/pages/CsmTimeCardsPage.tsx
Moves project, work-item, and engineer filtering to array-based multi-select state and uses SearchableMultiSelect in the filter bar.
E2E helpers and specs
apps/csm-portal/webapp/tests/e2e/pages/TimeCardsPage.ts, apps/csm-portal/webapp/tests/e2e/specs/timecards/*
Adds page-object helpers for filtering and clearing work-item filters and updates the timecards specs to use them.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SearchableMultiSelect
  participant CsmTimeCardsPage
  participant FilterBar
  User->>SearchableMultiSelect: select project or case number
  SearchableMultiSelect->>FilterBar: onChange(string[])
  FilterBar->>CsmTimeCardsPage: update filter arrays
  CsmTimeCardsPage->>CsmTimeCardsPage: recompute visible sheets and cards
  CsmTimeCardsPage-->>User: render filtered results and chips
Loading

Possibly related PRs

Suggested labels: Type/Improvement, Type/Bug

Suggested reviewers: rksk, Rashmika998, cloby99

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main time-cards changes: searchable filters, minutes-based handling, and stricter approver access.
Description check ✅ Passed All required template sections are present and substantially filled in, with clear details on purpose, approach, tests, and release note.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 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/components/SearchableMultiSelect.tsx`:
- Around line 17-18: The SearchableMultiSelect component is using the React
namespace for HTMLAttributes without importing it, so TypeScript will fail.
Update the imports in SearchableMultiSelect.tsx to bring in HTMLAttributes
explicitly, and replace the props cast in the Autocomplete render logic with the
imported type instead of React.HTMLAttributes<HTMLLIElement>.

In `@apps/csm-portal/webapp/tests/e2e/specs/timecards/my-sheets.spec.ts`:
- Around line 100-107: The my-sheets e2e flow clears the work item filter but
does not verify the post-clear state. Update the test in the my-sheets spec
around tc.clearFilters() to assert the filter was removed or that the sheet/card
list returned to an unfiltered state, using the existing tc helper methods and
the caseNumber-specific visibility checks already in place.
🪄 Autofix (Beta)

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

Run ID: 393ed4b0-f278-48f7-9c51-02b6b347a284

📥 Commits

Reviewing files that changed from the base of the PR and between d58fef2 and ff8a7b4.

📒 Files selected for processing (21)
  • apps/csm-portal/webapp/src/components/MultiSelectField.tsx
  • apps/csm-portal/webapp/src/components/SearchableMultiSelect.tsx
  • apps/csm-portal/webapp/src/features/csm-cases/components/CasesFilterBar.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/api/useTimeCards.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/api/useTimeSheets.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/components/CaseTimeCardsPanel.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/components/LogTimeCardDialog.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/components/TimeCardReviewDialog.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/components/TimeSheetCard.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/constants/timeCardConstants.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/hooks/useIsTeamLead.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/hooks/useTimecardRole.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/pages/CsmTimeCardsPage.tsx
  • apps/csm-portal/webapp/src/features/csm-timecards/types/timeCards.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/utils/__tests__/timeCardTotals.test.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/utils/__tests__/timeSheetGrouping.test.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/utils/timeCardTotals.ts
  • apps/csm-portal/webapp/src/features/csm-timecards/utils/timeSheetGrouping.ts
  • apps/csm-portal/webapp/tests/e2e/pages/TimeCardsPage.ts
  • apps/csm-portal/webapp/tests/e2e/specs/timecards/approvals.spec.ts
  • apps/csm-portal/webapp/tests/e2e/specs/timecards/my-sheets.spec.ts
💤 Files with no reviewable changes (1)
  • apps/csm-portal/webapp/src/features/csm-timecards/constants/timeCardConstants.ts

Comment thread apps/csm-portal/webapp/src/components/SearchableMultiSelect.tsx
Comment thread apps/csm-portal/webapp/tests/e2e/specs/timecards/my-sheets.spec.ts
…owns

Resolves the CasesFilterBar.tsx conflict: keeps the shared @components/
MultiSelectField.tsx extraction but updates its implementation to match
dev-app-csm-portal's newer Autocomplete+chip look (was Select+checkbox),
and drops the now-redundant local MultiSelectField/SearchableMultiSelect
definitions and unused imports.
…ons#1055

Import HTMLAttributes explicitly in SearchableMultiSelect instead of
relying on the ambient React namespace, matching MultiSelectField's
existing style. Also assert the work-item filter actually clears in
the my-sheets e2e test, not just that it applied.
@Hesara2003

Copy link
Copy Markdown
Contributor Author

Fixed both, pushed. Explicit React import in SearchableMultiSelect, and the my-sheets test now checks the filter actually clears.

@Hesara2003

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 6, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rksk

rksk commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@rksk
rksk merged commit 4eaf988 into wso2-open-operations:dev-app-csm-portal Jul 6, 2026
1 check passed
Rashmika998 pushed a commit that referenced this pull request Jul 6, 2026
…ilter

Reconciles the date-range filter and success-toast additions with the
now-merged searchable multi-select filters from PR #1055 (project/work
item/engineer went from plain strings to string[]).
@Hesara2003
Hesara2003 deleted the feature/timecards-filter-dropdowns branch July 6, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/CSM Portal Area/Frontend Platform/Web Type/New Feature Represents a request or task for a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants