Skip to content

Improve handling of missing primary email and mobile number#10086

Open
sadilchamishka wants to merge 3 commits intowso2:masterfrom
sadilchamishka:primary-mobile-not-showing-issue
Open

Improve handling of missing primary email and mobile number#10086
sadilchamishka wants to merge 3 commits intowso2:masterfrom
sadilchamishka:primary-mobile-not-showing-issue

Conversation

@sadilchamishka
Copy link
Copy Markdown
Contributor

Purpose

This pull request improves how multiple email addresses and mobile numbers are displayed and initialized in the user profile form, especially when the "multiple email and mobile number" feature is enabled. The logic now ensures that the primary email and mobile number are included in their respective lists if they're not already present, providing a more accurate and user-friendly experience.

Enhancements to user profile form initialization:

  • Ensures the primary email is included in the list of email addresses when multiple emails are enabled and avoids duplicates (user-profile-form.tsx).
  • Ensures the primary mobile number is included in the list of mobile numbers when multiple numbers are enabled and avoids duplicates (user-profile-form.tsx).

Documentation and changelog:

  • Adds a changeset entry describing the improvements to displaying multiple email addresses and mobile numbers. (.changeset/shaggy-wombats-whisper.md)

Related Issues

…ary email or mobile number is not included in the multi valued list
Copilot AI review requested due to automatic review settings April 7, 2026 08:43
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Patch-level changes: added a Changeset for user packages. Updated user-profile initialization to include primary email/mobile in multi-valued fields. Added getApprovalWorkflows API and refactored the approval-workflow creation form to perform imperative name-uniqueness checks on submit, removing the Redux-driven lookup.

Changes

Cohort / File(s) Summary
Release Documentation
.changeset/shaggy-wombats-whisper.md
Added a Changeset declaring patch releases for @wso2is/admin.users.v1 and @wso2is/console, noting improved display of multiple emails and mobile numbers.
User Profile Form
features/admin.users.v1/components/user-profile/user-profile-form.tsx
Updated prepareInitialValues to include the primary email/mobile in multi-valued fields when present (deduplicating by containment), removing reliance on the existing array being empty.
Approval Workflows (API & Form)
features/admin.approval-workflows.v1/api/approval-workflow.ts, features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx
Added exported getApprovalWorkflows(filter?: string): Promise<WorkflowListResponseInterface>; replaced Redux/query-based name-existence fetch with an imperative per-submit getApprovalWorkflows check in the create form, injecting validation errors via refs and programmatically triggering FinalForm revalidation.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely complete but missing required checklist items. It provides clear purpose and related issue, but the mandatory developer checklist is entirely unchecked. Complete the mandatory Developer Checklist section and verify/check off the applicable items from the main checklist to ensure proper tracking of behavioral changes and migration impacts.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: improving handling of missing primary email and mobile numbers in the user profile form.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Changeset Required ✅ Passed The pull request includes a valid changeset file at .changeset/shaggy-wombats-whisper.md documenting patch-level releases for affected packages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves initialization of the user profile form’s multi-valued email address and mobile number fields so that the primary email/mobile is always present in the corresponding list (when the multiple email/mobile feature is enabled), avoiding duplicate entries.

Changes:

  • Prepend the primary email to emailAddresses when missing (and multiple emails/mobiles is enabled).
  • Prepend the primary mobile number to mobileNumbers when missing (and multiple emails/mobiles is enabled).
  • Add a changeset documenting the patch-level improvement.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
features/admin.users.v1/components/user-profile/user-profile-form.tsx Ensures primary email/mobile are included in their multi-valued lists when missing, without duplicating existing entries.
.changeset/shaggy-wombats-whisper.md Records the patch change for @wso2is/admin.users.v1 and @wso2is/console.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +246 to 250
if (isMultipleEmailAndMobileNumberEnabled && primaryEmail && !emailAddresses.includes(primaryEmail)) {
(
initialValues[systemSchema] as Record<string, unknown>
)[emailAddressesField] = [ primaryEmail, ...emailAddresses ];
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

This initial-values logic for email/mobile lists looks very similar to the shared implementation in @wso2is/common.users.v1/utils/profile-utils (prepareInitialValues/getFlattenedInitialValues). Since this file now has slightly different behavior (inserting the primary value even when the list is non-empty), consider centralizing the behavior in the shared utility (or aligning both) to avoid future drift and inconsistent initialization across screens that rely on the common helper.

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.05%. Comparing base (b472565) to head (3516018).
⚠️ Report is 74 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #10086   +/-   ##
=======================================
  Coverage   56.05%   56.05%           
=======================================
  Files          42       42           
  Lines        1024     1024           
  Branches      254      246    -8     
=======================================
  Hits          574      574           
  Misses        416      416           
  Partials       34       34           
Flag Coverage Δ
@wso2is/core 56.05% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx (1)

63-66: ⚠️ Potential issue | 🔴 Critical

Breaking change: triggerSubmit is now async but interface and callers don't await it.

The triggerSubmit function is async (line 103), but:

  1. The interface at line 64 declares triggerSubmit: () => void instead of () => Promise<void>
  2. All callers across both files invoke triggerSubmit() without awaiting:
    • approval-workflow-create-page.tsx: lines 372–373, 428–429, 481–482, 534–535
    • approval-workflow-edit.tsx: lines 316, 730, 735, 737, 739

This causes race conditions where the name uniqueness check (performed by the async call) may complete after subsequent operations have started. The edit page explicitly relies on synchronous ordering with the comment "Order matters: notification must update ref before config submit reads it" (line 726).

Additionally:

  • Lines 90–91 use any type (violates explicit type annotations rule)
  • Line 107 uses inline type definition instead of a named interface

Update the interface to triggerSubmit: () => Promise<void> and await all callers, or refactor to perform the name uniqueness check on field blur/change rather than on submit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`
around lines 63 - 66, Update the GeneralApprovalWorkflowDetailsFormRef so
triggerSubmit is declared as triggerSubmit: () => Promise<void>, then update
every caller to await formRef.current.triggerSubmit() (ensuring the create/edit
pages that rely on ordering wait for the async name-uniqueness check to
complete); alternatively, move the name-uniqueness check off submit into
onBlur/onChange to avoid awaiting at call sites. Also replace the use of any
with an explicit type and extract the inline anonymous type used near the
triggerSubmit implementation into a named interface so all types are explicit
and consistent.
🧹 Nitpick comments (3)
features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx (3)

136-138: Consider logging the error for debugging purposes.

While silently failing to not block submission is reasonable, logging the error would help with debugging in production without affecting UX.

Suggested enhancement
                         } catch (_error: unknown) {
-                            // Silently fail — do not block submission on a lookup error.
+                            // Silently fail — do not block submission on a lookup error.
+                            console.warn("Workflow name uniqueness check failed:", _error);
                         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`
around lines 136 - 138, The catch block that currently swallows errors in
general-approval-workflow-details-form.tsx (catch (_error: unknown) { /*
Silently fail */ }) should log the caught error for observability without
changing UX; replace the silent catch with a logging call (e.g., catch (error) {
console.error('Lookup failed during submission in
GeneralApprovalWorkflowDetailsForm:', error); } or use the project's logger if
one exists) so the error is recorded but submission still proceeds.

90-91: Avoid any type—use proper FinalForm types.

The coding guidelines state to never use any. The formApiRef should use FormApi from final-form, and currentValuesRef should use the form values interface.

Suggested fix
+import { FormApi } from "final-form";
+
-            const currentValuesRef: any = useRef(null);
-            const formApiRef: MutableRefObject<any> = useRef<any>(null);
+            const currentValuesRef: MutableRefObject<GeneralDetailsFormValuesInterface | null> = useRef<GeneralDetailsFormValuesInterface | null>(null);
+            const formApiRef: MutableRefObject<FormApi<GeneralDetailsFormValuesInterface> | null> = useRef<FormApi<GeneralDetailsFormValuesInterface> | null>(null);

As per coding guidelines: "Never use any; use proper types or unknown with type guards."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`
around lines 90 - 91, The refs are typed as any; replace them with proper Final
Form types: import FormApi from 'final-form' and change formApiRef to
MutableRefObject<FormApi<ApprovalWorkflowFormValues> | null> (or the actual form
values interface name used in this component), and set currentValuesRef to
useRef<ApprovalWorkflowFormValues | null>(null) (or unknown with guarded access
if you prefer); update any usages to respect the concrete types and avoid `any`.

111-119: Use WorkflowListResponseInterface instead of inline type.

The response is typed inline as { workflows?: { id: string; name: string }[] }, but WorkflowListResponseInterface is already imported (via the API function's return type). Using the proper interface ensures type consistency.

Suggested fix
-                            const response: { workflows?: { id: string; name: string }[] } =
+                            const response: WorkflowListResponseInterface =
                                 await getApprovalWorkflows(currentName);

And add the import if not already available:

import { WorkflowListResponseInterface } from "../../models/approval-workflows";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`
around lines 111 - 119, Replace the inline response type with the shared
interface: change the type of the variable response (from the
getApprovalWorkflows call) to WorkflowListResponseInterface and ensure
WorkflowListResponseInterface is imported (e.g., from
"../../models/approval-workflows"); keep the rest of the logic using
response?.workflows as-is so type-checking uses the canonical interface
throughout (refer to the response variable and getApprovalWorkflows call to
locate the code).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`:
- Around line 63-66: Update the GeneralApprovalWorkflowDetailsFormRef so
triggerSubmit is declared as triggerSubmit: () => Promise<void>, then update
every caller to await formRef.current.triggerSubmit() (ensuring the create/edit
pages that rely on ordering wait for the async name-uniqueness check to
complete); alternatively, move the name-uniqueness check off submit into
onBlur/onChange to avoid awaiting at call sites. Also replace the use of any
with an explicit type and extract the inline anonymous type used near the
triggerSubmit implementation into a named interface so all types are explicit
and consistent.

---

Nitpick comments:
In
`@features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx`:
- Around line 136-138: The catch block that currently swallows errors in
general-approval-workflow-details-form.tsx (catch (_error: unknown) { /*
Silently fail */ }) should log the caught error for observability without
changing UX; replace the silent catch with a logging call (e.g., catch (error) {
console.error('Lookup failed during submission in
GeneralApprovalWorkflowDetailsForm:', error); } or use the project's logger if
one exists) so the error is recorded but submission still proceeds.
- Around line 90-91: The refs are typed as any; replace them with proper Final
Form types: import FormApi from 'final-form' and change formApiRef to
MutableRefObject<FormApi<ApprovalWorkflowFormValues> | null> (or the actual form
values interface name used in this component), and set currentValuesRef to
useRef<ApprovalWorkflowFormValues | null>(null) (or unknown with guarded access
if you prefer); update any usages to respect the concrete types and avoid `any`.
- Around line 111-119: Replace the inline response type with the shared
interface: change the type of the variable response (from the
getApprovalWorkflows call) to WorkflowListResponseInterface and ensure
WorkflowListResponseInterface is imported (e.g., from
"../../models/approval-workflows"); keep the rest of the logic using
response?.workflows as-is so type-checking uses the canonical interface
throughout (refer to the response variable and getApprovalWorkflows call to
locate the code).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: a8a87c86-e4c1-491b-9d54-bdad7f4b8766

📥 Commits

Reviewing files that changed from the base of the PR and between 75ef6a9 and 3516018.

📒 Files selected for processing (2)
  • features/admin.approval-workflows.v1/api/approval-workflow.ts
  • features/admin.approval-workflows.v1/components/create/general-approval-workflow-details-form.tsx

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants