Skip to content

Improve workflow executor task UI rendering for dynamic properties (Admin + Publisher)#1258

Merged
PasanT9 merged 10 commits intowso2:mainfrom
JanithaSampathBandara:improvement/workflow-executors-dynamic-rendering
Mar 13, 2026
Merged

Improve workflow executor task UI rendering for dynamic properties (Admin + Publisher)#1258
PasanT9 merged 10 commits intowso2:mainfrom
JanithaSampathBandara:improvement/workflow-executors-dynamic-rendering

Conversation

@JanithaSampathBandara
Copy link
Copy Markdown

@JanithaSampathBandara JanithaSampathBandara commented Feb 26, 2026

Summary

  • Improves workflow approval task rendering in Admin and Publisher portals to support dynamic properties (including nested objects/arrays) returned by workflow executors.

Admin portal

  • Update workflow task screens to render request details dynamically based on received property type (primitive/object/array).
  • Add reusable WorkflowApprovalTasks component for consistent rendering across workflow types.

Publisher portal

  • Update Subscription create/update screens to support the improved workflow rendering.

Samples

Application creation workflow task

application-creation-pending-request

Application update workflow task

application-pending-details

Subscription create workflow task

subscription-creation-pending-list-in-publisher-portal

Subscription update workflow task

subscription-update-approval-in-publisher

Dependency

Testing

  • Admin: (cd portals/admin/src/main/webapp && npm run build:dev)
  • Publisher: (cd portals/publisher/src/main/webapp && npm run build:dev)

Summary by CodeRabbit

  • New Features

    • Added a unified WorkflowApprovalTasks view with search, expandable details, reload, and per-item approve/reject actions.
  • Refactor

    • Multiple workflow screens now delegate to the unified approval tasks view for consistent UI and behavior, reducing duplicated logic.
  • Localization

    • Consolidated per-entity workflow translations under Workflow.Common; standardized empty states, permission messages, help links, and search placeholders.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


JanithaSampathBandara seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Multiple per-entity workflow UI components were refactored to delegate to a new shared WorkflowApprovalTasks component; locale bundles in admin and publisher were consolidated by removing many per-entity Workflow.* keys and adding unified Workflow.Common.* keys.

Changes

Cohort / File(s) Summary
Localization (Admin)
portals/admin/.../site/public/locales/en.json, portals/admin/.../site/public/locales/fr.json
Removed many per-entity Workflow.* translation keys; added consolidated Workflow.Common.* keys (empty states, errors, headers, actions, permission messages, update messages). Minor phrasing/punctuation tweaks and a few unrelated locale additions.
Localization (Publisher)
portals/publisher/.../site/public/locales/en.json
Added Workflow.Common.* keys and other small keys; removed deprecated per-entity Workflow.* keys and subscription-specific keys; adjusted search/title keys.
Admin: Workflow Component Wrappers
portals/admin/.../source/src/app/components/Workflow/APIRevisionDeployment.jsx, .../APIStateChange.jsx, .../ApplicationCreation.jsx, .../ApplicationDeletion.jsx, .../ApplicationUpdate.jsx, .../RegistrationCreation.jsx, .../SubscriptionCreation.jsx, .../SubscriptionDeletion.jsx, .../SubscriptionUpdate.jsx, .../UserCreation.jsx
Replaced heavy, stateful ListLabels implementations with lightweight wrappers that render WorkflowApprovalTasks configured by props (workflowTypes, title, helpLink, searchPlaceholder, maxColumnsIncludingAction). Removed per-file data fetching, action handlers, and bespoke UI logic.
Publisher: Subscription Components
portals/publisher/.../source/src/app/components/Subscription/.../SubscriptionCreation.jsx, .../SubscriptionUpdate.jsx
Refactored to delegate to WorkflowApprovalTasks; removed local data fetching, state management, and custom table rendering.
New Shared Components (Admin & Publisher)
portals/admin/.../Workflow/WorkflowApprovalTasks.jsx, portals/publisher/.../Workflow/WorkflowApprovalTasks.jsx
Added comprehensive WorkflowApprovalTasks components: fetch pending workflows for provided types, normalize properties into simple vs JSON, render dynamic tables with search/reload, expandable JSON details, and per-row Approve/Reject actions with backend calls, permission handling, and alerts. Large new component logic to review.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant WAT as WorkflowApprovalTasks
    participant API as API
    participant Backend as Backend

    User->>WAT: Mount with workflowTypes / interact (search, expand)
    WAT->>API: GET /workflows?types=...
    API->>Backend: Query workflow store
    Backend-->>API: Return workflows
    API-->>WAT: Workflows list
    WAT->>WAT: Normalize & split properties (simple / JSON)
    WAT-->>User: Render table with columns and expand controls
    User->>WAT: Click Expand / Search
    WAT-->>User: Show details / filtered results
    User->>WAT: Click Approve or Reject
    WAT->>API: POST /workflows/{id}/action {approve|reject}
    API->>Backend: Update workflow status
    Backend-->>API: Acknowledge update
    API-->>WAT: Success/Error
    WAT->>WAT: Refresh list / show alert
    WAT-->>User: Updated list or error message
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Hopping through keys and components anew,
I stitched many workflows into one snug view.
Approve and reject, search and expand with glee,
JSON burrows open for all to see.
Tiny paws applaud — one task tree for me.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main change: improving workflow executor task UI rendering to handle dynamic properties across both Admin and Publisher portals.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan for PR comments
  • Generate coding plan

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

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

Actionable comments posted: 9

🧹 Nitpick comments (4)
portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx (1)

743-750: Localize static detail labels in expandable rows.

Description and Created are hardcoded English strings here, while the component otherwise follows react-intl.

🌐 Suggested refactor
-                                <Typography variant='body2' sx={{ mt: 1 }}>
-                                    <strong>Description: </strong>
+                                <Typography variant='body2' sx={{ mt: 1 }}>
+                                    <strong>
+                                        <FormattedMessage
+                                            id='Workflow.Common.expand.field.description'
+                                            defaultMessage='Description'
+                                        />
+                                        {': '}
+                                    </strong>
                                     {toText(row?.description)}
                                 </Typography>

                                 <Typography variant='body2' sx={{ mt: 1 }}>
-                                    <strong>Created: </strong>
+                                    <strong>
+                                        <FormattedMessage
+                                            id='Workflow.Common.expand.field.created'
+                                            defaultMessage='Created'
+                                        />
+                                        {': '}
+                                    </strong>
                                     {row?.createdTime ? (
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 743 - 750, Replace the hardcoded English labels "Description" and
"Created" in the expandable-row Typography blocks inside
WorkflowApprovalTasks.jsx with react-intl localized messages (use either
<FormattedMessage id="..." defaultMessage="..." /> or intl.formatMessage) so the
component follows the app's i18n pattern; update the two Typography lines that
render <strong>Description: </strong> and <strong>Created: </strong> (they
appear alongside toText(row?.description) and row?.createdTime) to use localized
message IDs such as "workflow.description" and "workflow.created" (include
sensible defaultMessage values) and keep the existing structure (strong tag,
toText, and createdTime handling) intact.
portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx (1)

6-26: Same naming concern as other workflow components.

The function is named ListLabels but handles Subscription Deletion workflow. Consider renaming to SubscriptionDeletion for consistency and clarity. The implementation otherwise correctly delegates to WorkflowApprovalTasks.

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

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx`
around lines 6 - 26, Rename the ListLabels component to SubscriptionDeletion to
reflect its purpose and match other workflow components; update the function
declaration (currently ListLabels) to SubscriptionDeletion, adjust any default
or named exports and import sites that reference ListLabels, and keep the JSX
unchanged (it should still render WorkflowApprovalTasks with workflowTypes
['AM_SUBSCRIPTION_DELETION'] and the intl-formatted title, helpLink,
searchPlaceholder, and maxColumnsIncludingAction props).
portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx (1)

6-26: Consider renaming ListLabels to a more descriptive name.

The function is named ListLabels but it handles Subscription Creation workflow approval tasks. This naming is misleading and inconsistent with the component's actual purpose. Consider renaming to SubscriptionCreation or SubscriptionCreationWorkflow for clarity.

♻️ Suggested rename
-function ListLabels() {
+function SubscriptionCreation() {
     const intl = useIntl();
     ...
 }

-export default ListLabels;
+export default SubscriptionCreation;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx`
around lines 6 - 26, The component function ListLabels is misnamed for its
purpose; rename the function ListLabels to a descriptive name such as
SubscriptionCreation or SubscriptionCreationWorkflow and update any
references/exports accordingly so the component that renders
WorkflowApprovalTasks (props: workflowTypes, title, helpLink, searchPlaceholder,
maxColumnsIncludingAction) reflects the new name; ensure the default export or
import sites use the new identifier and run a quick search/replace for
ListLabels to update all usages.
portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx (1)

921-923: Use a shared i18n key for the generic no-data state.

Since this component is reused across workflow types, a subscription-specific translation key is brittle. Consider moving this to a Workflow.Common.* key for consistency.

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

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 921 - 923, The FormattedMessage in WorkflowApprovalTasks.jsx uses a
subscription-specific i18n key
('Workflow.SubscriptionCreation.ListBase.nodata.message') which is brittle
across workflows; update the component to use a shared generic key (e.g.
'Workflow.Common.nodata.message') instead, and ensure the corresponding
translation entry is added/updated in the i18n resource files so all workflow
components can reuse it; locate the FormattedMessage usage in
WorkflowApprovalTasks (and any similar components) and replace the id with the
shared key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/APIRevisionDeployment.jsx`:
- Around line 20-22: Update the user-facing placeholder string used in
APIRevisionDeployment.jsx for the message id
'Workflow.APIRevisionDeployment.search.default' by fixing the typo: replace
"Search by Revision Id, API Name, Environment etcC" with a corrected version
such as "Search by Revision Id, API Name, Environment, etc." and ensure any
related translation keys/resources that mirror this defaultMessage are updated
accordingly.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 237-238: The current loading state uses shared isUpdating and
buttonValue, causing every row to show a spinner for the same action; change
state to include the active row id and action by adding a new piece of state
(e.g., activeReferenceId or activeUpdate {referenceId, action}) and update
handlers (where setIsUpdating/setButtonValue are used) to set that active id +
action when a button is clicked and clear it when the request finishes or
errors; then update the button render logic to show the spinner only when
activeReferenceId === row.referenceId (and action matches buttonValue) instead
of relying on the global isUpdating/buttonValue so only the clicked row displays
loading.
- Around line 344-359: In the .catch block of updateStatus in
WorkflowApprovalTasks.jsx (the promise catch that currently does "throw
description"), stop throwing the raw string and instead surface the message via
the existing UI error path (e.g., call Alert.error(description) or set an error
state) so the click handler won't produce an unhandled rejection; keep the
existing intl.formatMessage fallback behavior and ensure the function
returns/ends normally after showing the error instead of rethrowing.
- Line 183: The forEach callback currently uses an expression body "(k) =>
keys.add(k)" which implicitly returns the Set.add() value and triggers the lint
rule; change the callback to a block body so it does not return a value — e.g.
replace "Object.keys(obj).forEach((k) => keys.add(k))" with a block-style
callback such as "Object.keys(obj).forEach((k) => { keys.add(k); })" (or use a
for...of loop) to eliminate the implicit return from keys.add.

In `@portals/publisher/src/main/webapp/site/public/locales/en.json`:
- Line 2508: Update the user-facing string for key
"Workflow.Common.permission.denied.content" in en.json to correct grammar:
replace "dont" with "don't", change "permission" to "permissions", and make
casing consistent (e.g., "approval tasks"); for example use "You don't have
sufficient permissions to view approval tasks. Please contact the site
administrator." Ensure you edit the value for the exact key
"Workflow.Common.permission.denied.content".

In
`@portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionUpdate/SubscriptionUpdate.jsx`:
- Around line 12-14: The i18n key used in the SubscriptionUpdate component is
inconsistently namespaced: update the id passed to intl.formatMessage in the
title prop from "Workflow.SubscriptionCreation.title.subscriptionupdate" to a
clearer, consistent key such as
"Workflow.SubscriptionUpdate.title.subscriptionupdate" (and then add or rename
the matching entry in your en.json locales file). Locate the title usage in
SubscriptionUpdate.jsx (the intl.formatMessage call) and change the id string,
then update the locale resource (or add an alias) so the new key resolves to the
same human-readable title.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 237-238: The current isUpdating/buttonValue state is global so
multiple rows can show the spinner; replace or extend that state to include the
row identifier (e.g., track { isUpdating, buttonValue, referenceId } or add a
separate selectedActionReference state) and update all action handlers (where
setIsUpdating and setButtonValue are called) to also set the referenceId for the
clicked row; then change the spinner/render condition so it only shows when
isUpdating is true AND buttonValue matches the action AND referenceId matches
the current row's id. Apply the same change for the other occurrences referenced
(around lines with setIsUpdating/setButtonValue at the noted locations).
- Around line 181-184: The lint error comes from the inner forEach callback
implicitly returning the result of keys.add(k); update the callback used in
Object.keys(obj).forEach to a block-bodied function so it doesn't return a value
(e.g., replace (k) => keys.add(k) with (k) => { keys.add(k); }), leaving
arr.forEach and keys.add untouched.
- Around line 838-840: Update the user-facing permission-denied message in
WorkflowApprovalTasks.jsx: locate the string that currently reads 'You dont have
enough permission to view Approval Tasks. Please contact the site
administrator.' (used in the WorkflowApprovalTasks component/render) and correct
the grammar by changing "dont" to "don't" so the message becomes "You don't have
enough permission to view Approval Tasks. Please contact the site
administrator."

---

Nitpick comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx`:
- Around line 6-26: The component function ListLabels is misnamed for its
purpose; rename the function ListLabels to a descriptive name such as
SubscriptionCreation or SubscriptionCreationWorkflow and update any
references/exports accordingly so the component that renders
WorkflowApprovalTasks (props: workflowTypes, title, helpLink, searchPlaceholder,
maxColumnsIncludingAction) reflects the new name; ensure the default export or
import sites use the new identifier and run a quick search/replace for
ListLabels to update all usages.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx`:
- Around line 6-26: Rename the ListLabels component to SubscriptionDeletion to
reflect its purpose and match other workflow components; update the function
declaration (currently ListLabels) to SubscriptionDeletion, adjust any default
or named exports and import sites that reference ListLabels, and keep the JSX
unchanged (it should still render WorkflowApprovalTasks with workflowTypes
['AM_SUBSCRIPTION_DELETION'] and the intl-formatted title, helpLink,
searchPlaceholder, and maxColumnsIncludingAction props).

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 743-750: Replace the hardcoded English labels "Description" and
"Created" in the expandable-row Typography blocks inside
WorkflowApprovalTasks.jsx with react-intl localized messages (use either
<FormattedMessage id="..." defaultMessage="..." /> or intl.formatMessage) so the
component follows the app's i18n pattern; update the two Typography lines that
render <strong>Description: </strong> and <strong>Created: </strong> (they
appear alongside toText(row?.description) and row?.createdTime) to use localized
message IDs such as "workflow.description" and "workflow.created" (include
sensible defaultMessage values) and keep the existing structure (strong tag,
toText, and createdTime handling) intact.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 921-923: The FormattedMessage in WorkflowApprovalTasks.jsx uses a
subscription-specific i18n key
('Workflow.SubscriptionCreation.ListBase.nodata.message') which is brittle
across workflows; update the component to use a shared generic key (e.g.
'Workflow.Common.nodata.message') instead, and ensure the corresponding
translation entry is added/updated in the i18n resource files so all workflow
components can reuse it; locate the FormattedMessage usage in
WorkflowApprovalTasks (and any similar components) and replace the id with the
shared key.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e10d292 and a1188a8.

📒 Files selected for processing (16)
  • portals/admin/src/main/webapp/site/public/locales/en.json
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIRevisionDeployment.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/RegistrationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/UserCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionCreation/SubscriptionCreation.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionUpdate/SubscriptionUpdate.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx

@JanithaSampathBandara JanithaSampathBandara force-pushed the improvement/workflow-executors-dynamic-rendering branch from a1188a8 to 160e35d Compare March 2, 2026 20:33
Copy link
Copy Markdown

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
portals/admin/src/main/webapp/site/public/locales/fr.json (1)

727-737: ⚠️ Potential issue | 🟡 Minor

French locale file contains English text.

The new translation keys added to fr.json have English values instead of French translations:

  • Line 727: "Application Configuration Constraints" → should be French (e.g., "Contraintes de configuration de l'application")
  • Line 737: "Expand to configure constraints" → should be French (e.g., "Développer pour configurer les contraintes")

This will result in French-speaking users seeing English text for these UI elements.

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

In `@portals/admin/src/main/webapp/site/public/locales/fr.json` around lines 727 -
737, Replace the English values for the two French locale keys with proper
French translations: update the value of
"KeyManagers.AddEditKeyManager.app.config.constraints" (currently "Application
Configuration Constraints") to a French string such as "Contraintes de
configuration de l'application", and update
"KeyManagers.AddEditKeyManager.constraints.hidden.help" (currently "Expand to
configure constraints") to a French string such as "Développer pour configurer
les contraintes"; ensure you only change the right-hand JSON values in fr.json
and keep the keys unchanged.
♻️ Duplicate comments (1)
portals/publisher/src/main/webapp/site/public/locales/en.json (1)

2511-2511: ⚠️ Potential issue | 🟡 Minor

Use plural “permissions” in the permission-denied copy.

This is user-facing grammar and should read naturally.

✍️ Proposed text fix
-  "Workflow.Common.permission.denied.content": "You don't have enough permission to view Approval Tasks. Please contact the site administrator.",
+  "Workflow.Common.permission.denied.content": "You don't have enough permissions to view approval tasks. Please contact the site administrator.",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@portals/publisher/src/main/webapp/site/public/locales/en.json` at line 2511,
Update the user-facing message for the JSON key
"Workflow.Common.permission.denied.content" to use the plural "permissions"
instead of "permission" so the value reads: "You don't have enough permissions
to view Approval Tasks. Please contact the site administrator." Replace the
existing string value for that key in en.json.
🧹 Nitpick comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx (1)

62-63: Use default import instead of namespace import for consistency with TypeScript configuration.

Line 62 uses a namespace import, but the project's tsconfig.json has esModuleInterop: true enabled. While the namespace import pattern works with this configuration, the recommended practice when esModuleInterop is enabled is to use a default import. Lines 718-720 call dayjs(...) directly, which is idiomatic with a default import style.

Suggested improvement
-import * as dayjs from 'dayjs';
+import dayjs from 'dayjs';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 62 - 63, Replace the namespace import of dayjs with a default
import to match the project's esModuleInterop style: change the import line that
currently uses "import * as dayjs from 'dayjs'" to a default import and ensure
all usages (e.g., calls like dayjs(...) around the code, notably where dayjs is
invoked at lines referred in the review) continue to work; update the import
near the top of WorkflowApprovalTasks.jsx so other references (e.g., where
relativeTime plugin is extended) remain compatible with the default-import form.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@portals/admin/src/main/webapp/site/public/locales/en.json`:
- Line 1286: Update the value for the JSON key
"Workflow.Common.apicall.has.errors" to a clearer phrasing; replace "Unable to
get workflow pending requests" with "Unable to retrieve pending workflow
requests" (or similar concise wording) so the error toast reads naturally and
consistently across the UI.

In `@portals/admin/src/main/webapp/site/public/locales/fr.json`:
- Around line 1285-1311: The new French locale entries under keys like
"Workflow.Common.List.empty.content", "Workflow.Common.permission.denied.title",
"Workflow.Common.table.button.approve", "Workflow.Common.table.button.reject"
and all "Workflow.*.search.default"/"*.title.*" keys are still in English;
replace each English value with the correct French translation (e.g., "There are
no pending workflow requests." → "Il n'y a pas de demandes de workflow en
attente.", "Permission Denied" → "Permission refusée", "Approve"/"Reject" →
"Approuver"/"Rejeter") and verify all ~25 added entries are translated
consistently for the fr.json locale.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 682-683: In WorkflowApprovalTasks.jsx update the help link usage:
wherever the Link component renders with target='_blank' (the Link instance that
uses href={helpLink} and ListItemText), add rel='noopener noreferrer' to the
Link props to harden new-tab links against opener-based attacks; ensure the same
change is applied to any other Link or <a> usages in this component that open in
a new tab.

---

Outside diff comments:
In `@portals/admin/src/main/webapp/site/public/locales/fr.json`:
- Around line 727-737: Replace the English values for the two French locale keys
with proper French translations: update the value of
"KeyManagers.AddEditKeyManager.app.config.constraints" (currently "Application
Configuration Constraints") to a French string such as "Contraintes de
configuration de l'application", and update
"KeyManagers.AddEditKeyManager.constraints.hidden.help" (currently "Expand to
configure constraints") to a French string such as "Développer pour configurer
les contraintes"; ensure you only change the right-hand JSON values in fr.json
and keep the keys unchanged.

---

Duplicate comments:
In `@portals/publisher/src/main/webapp/site/public/locales/en.json`:
- Line 2511: Update the user-facing message for the JSON key
"Workflow.Common.permission.denied.content" to use the plural "permissions"
instead of "permission" so the value reads: "You don't have enough permissions
to view Approval Tasks. Please contact the site administrator." Replace the
existing string value for that key in en.json.

---

Nitpick comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 62-63: Replace the namespace import of dayjs with a default import
to match the project's esModuleInterop style: change the import line that
currently uses "import * as dayjs from 'dayjs'" to a default import and ensure
all usages (e.g., calls like dayjs(...) around the code, notably where dayjs is
invoked at lines referred in the review) continue to work; update the import
near the top of WorkflowApprovalTasks.jsx so other references (e.g., where
relativeTime plugin is extended) remain compatible with the default-import form.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a1188a8 and 160e35d.

📒 Files selected for processing (17)
  • portals/admin/src/main/webapp/site/public/locales/en.json
  • portals/admin/src/main/webapp/site/public/locales/fr.json
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIRevisionDeployment.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/RegistrationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/UserCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionCreation/SubscriptionCreation.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionUpdate/SubscriptionUpdate.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionUpdate/SubscriptionUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx

Copy link
Copy Markdown

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx (1)

256-260: Prefer partial aggregation over all-or-nothing multi-type fetches.

Promise.all makes one failed workflow-type request fail the whole table load. For a shared multi-type component, Promise.allSettled gives better resilience.

♻️ Suggested refactor
- return Promise.all(types.map((t) => restApi.workflowsGet(t)))
-     .then((results) => {
-         const combined = results.flatMap((r) => r?.body?.list || []);
+ return Promise.allSettled(types.map((t) => restApi.workflowsGet(t)))
+     .then((results) => {
+         const fulfilled = results
+             .filter((r) => r.status === 'fulfilled')
+             .map((r) => r.value);
+         const rejected = results.filter((r) => r.status === 'rejected');
+
+         if (fulfilled.length === 0) {
+             throw rejected[0]?.reason || new Error('Unable to retrieve workflow requests');
+         }
+
+         const combined = fulfilled.flatMap((r) => r?.body?.list || []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 256 - 260, The current use of Promise.all over types.map((t) =>
restApi.workflowsGet(t)) makes one failing workflowsGet call abort the whole
load; change it to Promise.allSettled(...) and then iterate the settled results
to collect only fulfilled responses (extract r.value.body.list or similar) into
the combined array used by the table (the combined variable), optionally logging
rejected entries for diagnostics; update the then(...) handler in
WorkflowApprovalTasks.jsx to flatMap only fulfilled results and handle
empty/failed fetches gracefully.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 276-287: The 401 handler sets hasListPermission(false) but
successful fetch paths never reset it, causing a sticky "Permission Denied"
view; update the success branches in the fetch handlers inside
WorkflowApprovalTasks.jsx (the promise .then handlers that populate pending
requests and the other fetch block around lines 295-303) to call
setHasListPermission(true) (and clear any previous error state if present)
before updating state with the fetched data so transient 401s don't permanently
hide the UI.
- Around line 880-894: The TextField used for search relies only on placeholder
text and lacks an accessible name; update the TextField (the component instance
using TextField with onChange={(e) => setSearchText(e.target.value)} and
placeholder={searchPlaceholder}) to provide an explicit accessible label—e.g.
add an aria-label or a visible/hidden label via the TextField's label or
InputProps.inputProps (e.g. inputProps: { 'aria-label': 'Search tasks' }) so
assistive technologies can identify the control consistently.
- Around line 751-764: Replace the two hard-coded labels "Description:" and
"Created:" inside the WorkflowApprovalTasks.jsx expandable-row rendering with
the component's i18n API (e.g., intl.formatMessage or <FormattedMessage>) so
they use the same translation keys as the rest of the UI; locate the JSX around
the toText(row?.description) and the createdTime/Tooltip block and swap the
literal strings for calls to the i18n helper (providing sensible message ids
like workflow.description and workflow.created and default messages) so the
labels are localized consistently.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 276-287: Before initiating each API fetch that branches on
permission, reset the permission flag so a prior 401 can't "stick": call
setHasListPermission(true) at the start of the fetch flow (before the promise
chain that contains the .catch block shown) so successful responses can
re-enable the normal view; update each similar fetch in this component
(including the other .catch handlers referenced) to setHasListPermission(true)
before calling the API, and keep the existing .catch logic that sets
setHasListPermission(false) on 401.

---

Nitpick comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 256-260: The current use of Promise.all over types.map((t) =>
restApi.workflowsGet(t)) makes one failing workflowsGet call abort the whole
load; change it to Promise.allSettled(...) and then iterate the settled results
to collect only fulfilled responses (extract r.value.body.list or similar) into
the combined array used by the table (the combined variable), optionally logging
rejected entries for diagnostics; update the then(...) handler in
WorkflowApprovalTasks.jsx to flatMap only fulfilled results and handle
empty/failed fetches gracefully.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 160e35d and 55ba378.

📒 Files selected for processing (4)
  • portals/admin/src/main/webapp/site/public/locales/en.json
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx

Copy link
Copy Markdown

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
portals/publisher/src/main/webapp/site/public/locales/en.json (1)

2529-2531: Consider consolidating the shared search placeholder under Workflow.Common.*.

The SubscriptionUpdate.jsx component (per context snippet 3) reuses Workflow.SubscriptionCreation.search.default for its search placeholder. Since both workflows share this text and other keys have been consolidated under Workflow.Common.*, moving this to Workflow.Common.search.placeholder would improve namespace consistency.

Current cross-reference pattern:

SubscriptionUpdate.jsx → Workflow.SubscriptionCreation.search.default

Suggested pattern (aligns with consolidation approach):

SubscriptionCreation.jsx → Workflow.Common.search.placeholder
SubscriptionUpdate.jsx  → Workflow.Common.search.placeholder

This is a minor organizational improvement and not blocking.

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

In `@portals/publisher/src/main/webapp/site/public/locales/en.json` around lines
2529 - 2531, Move the shared search placeholder key from
"Workflow.SubscriptionCreation.search.default" into a common namespace
"Workflow.Common.search.placeholder" and update any components that reference it
(e.g., SubscriptionCreation.jsx and SubscriptionUpdate.jsx) to use the new key;
ensure you remove or deprecate the old
"Workflow.SubscriptionCreation.search.default" entry from the JSON to avoid
duplication and update any tests/localization lookups that reference the
original key to the new "Workflow.Common.search.placeholder".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 595-630: The cells use toText(...) and therefore flatten nested
objects/arrays; update the cells in renderObjectAsKeyValueTable (the
entries.map([...]) TableRow/TableCell for value) and the similar
structured-table branch to detect arrays/objects (typeof v === 'object' && v !==
null), and when found render them recursively (for objects call
renderObjectAsKeyValueTable with the nested key/object, for arrays render a
small list/table or map each item and call renderObjectAsKeyValueTable when
items are objects) instead of falling back to toText; keep toText as the
fallback for primitives and null/undefined so nested structures are dynamically
expanded.
- Around line 743-795: The table can end up showing only the Action column
because the 'description' column is always hidden and 'visibleKeys' is derived
solely from simpleProperties; update the columns construction (the cols array in
the useMemo where visibleKeys is iterated) to ensure an identifying column is
visible as a fallback: make the 'description' column display true when
visibleKeys is empty OR add a fallback column for 'referenceId' that is always
displayed (use the same customBodyRender pattern referencing filteredData and
row.referenceId and reuse renderInlineActions where appropriate); ensure the
column definitions still respect sorting/filtering options but explicitly set
display for the fallback identifier so rows with only nested payloads remain
distinguishable.
- Around line 1063-1080: Current code hides the MUIDataTable whenever
filteredData is an empty array and instead renders a static "No items yet"
message, which prevents the table's built-in noMatch text
(options.textLabels.body.noMatch) from showing on search misses; change the
logic to always render <MUIDataTable> when filteredData is defined (pass
filteredData even if empty) and remove the separate branch that returns the
Typography "No items yet" so the table can display its configured noMatch text
(look for filteredData, MUIDataTable, options, and textLabels.body.noMatch to
implement this).

---

Nitpick comments:
In `@portals/publisher/src/main/webapp/site/public/locales/en.json`:
- Around line 2529-2531: Move the shared search placeholder key from
"Workflow.SubscriptionCreation.search.default" into a common namespace
"Workflow.Common.search.placeholder" and update any components that reference it
(e.g., SubscriptionCreation.jsx and SubscriptionUpdate.jsx) to use the new key;
ensure you remove or deprecate the old
"Workflow.SubscriptionCreation.search.default" entry from the JSON to avoid
duplication and update any tests/localization lookups that reference the
original key to the new "Workflow.Common.search.placeholder".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ebfc7812-f84f-4df4-ab3a-526a042989d1

📥 Commits

Reviewing files that changed from the base of the PR and between 55ba378 and 5f7e210.

📒 Files selected for processing (5)
  • portals/admin/src/main/webapp/site/public/locales/en.json
  • portals/admin/src/main/webapp/site/public/locales/fr.json
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx

@JanithaSampathBandara JanithaSampathBandara force-pushed the improvement/workflow-executors-dynamic-rendering branch from 5f7e210 to bf3faec Compare March 9, 2026 12:12
Copy link
Copy Markdown

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

Actionable comments posted: 5

♻️ Duplicate comments (3)
portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx (3)

456-470: ⚠️ Potential issue | 🟠 Major

Keep an identifier visible when a row has only JSON properties.

visibleKeys is computed only from simpleProperties, and description is always hidden. For workflows whose payload is entirely nested, the main table collapses to an Action-only row, so users cannot tell which request they are approving or rejecting.

Also applies to: 743-752

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

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 456 - 470, visibleKeys is built only from row.simpleProperties so
rows whose payload is entirely nested render no identifying column (only
Action); modify the visibleKeys computation in WorkflowApprovalTasks.jsx to also
consider a fallback identifier (e.g., include 'description' or the top-level
key(s) from the row when simpleProperties is empty) before slicing to maxSimple;
update the logic that builds keys (the block using filteredData,
simpleProperties, keys Set, sorted, max/maxSimple and
DEFAULT_MAX_COLUMNS_INCLUDING_ACTION) to add the fallback identifier only when
no simple property keys are present so the table always shows an identifier
column.

1063-1080: ⚠️ Potential issue | 🟡 Minor

Let MUIDataTable handle empty search results.

This branch replaces the table with "No items yet" whenever filteredData is empty, so a search miss gets the wrong empty-state message instead of the configured textLabels.body.noMatch.

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

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 1063 - 1080, The component is hiding the MUIDataTable when
filteredData is an empty array and showing a static "No items yet" message,
which prevents MUIDataTable from displaying its configured search-empty
textLabels.body.noMatch; remove the conditional branch that replaces the table
when filteredData.length === 0 and instead always render <MUIDataTable> (when
filteredData is defined) passing the filteredData (even if empty) and the
existing options so the table can show its built-in noMatch message; if you need
a different initial-empty message for the unfiltered state, handle that
separately by checking the original data source (not filteredData) before
rendering but do not block the table from rendering on empty filtered results.

627-630: ⚠️ Potential issue | 🟠 Major

Nested values still get flattened after the first level.

Both structured-table branches render cell values with toText(...), so nested objects/arrays end up as JSON strings instead of using the dynamic renderer. Payloads like { config: { endpoints: [...] } } or [{ changes: { ... } }] will still lose their nested structure here.

Also applies to: 672-681

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

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`
around lines 627 - 630, The current structured-table rows call toText(...) for
both key and value in entries.map (rendering inside TableRow/TableCell), which
stringifies nested objects/arrays and flattens deeper structure; replace the
toText(v) call (and any toText(...) usages in the other structured-table branch
around the 672-681 block) with the file's dynamic value renderer used elsewhere
(the function/component responsible for rendering nested objects/arrays instead
of JSON strings—e.g., the existing renderDynamicValue/DynamicValue component or
renderValue function in this file), so complex values (objects/arrays) are
passed to that renderer and rendered recursively rather than being
JSON-stringified. Ensure TableCell receives the renderer output instead of a
plain string.
🧹 Nitpick comments (2)
portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx (1)

10-23: Push the shared workflow-page defaults into WorkflowApprovalTasks.

helpLink and maxColumnsIncludingAction={5} are repeated across the new wrapper components, so any future change to the generic workflow page contract now has to be updated in multiple files. Moving those defaults into WorkflowApprovalTasks would keep these wrappers focused on workflow-specific values only.

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

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx`
around lines 10 - 23, The wrapper repeats generic defaults (helpLink and
maxColumnsIncludingAction={5}) when rendering WorkflowApprovalTasks; refactor by
moving those defaults into the WorkflowApprovalTasks component so wrappers only
pass workflow-specific props. Update WorkflowApprovalTasks to set a default prop
or internal fallback for helpLink (e.g., derived from Configurations.app.docUrl
+ 'consume/manage-application/advanced-topics/workflows/') and for
maxColumnsIncludingAction (default 5), remove these props from wrappers like
ApplicationCreation.jsx, and ensure existing callers still override them when
needed.
portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx (1)

6-6: Consider adding a default value for isAPIProduct prop.

When rendered via the API State Change route (per RouteMenuMapping.jsx), this component is passed without props, making isAPIProduct undefined. While the falsy evaluation works correctly, adding an explicit default improves clarity and self-documentation.

✨ Suggested change
-function ListLabels({ isAPIProduct }) {
+function ListLabels({ isAPIProduct = false }) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx`
at line 6, The ListLabels component's isAPIProduct prop can be undefined when
the component is rendered without props (e.g., from the API State Change route);
add an explicit default so its intent is clear and to avoid relying on implicit
falsiness—either set a default parameter value in the function signature
(function ListLabels({ isAPIProduct = false }) { ... }) or define a
defaultProps/static default (ListLabels.defaultProps = { isAPIProduct: false })
so isAPIProduct is always boolean when referenced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 269-295: The code currently ignores rejected results from
Promise.allSettled and returns a partial workflow list; change this to detect
rejected.length > 0 and surface an error instead of silently dropping data: map
the settled results back to the original types (use the same order as types ->
results), build an aggregated error message listing the failed workflow types
and their rejection reasons, and throw that Error (or return a rejected Promise)
before constructing combined/ workflowList; use the existing variables results,
types, rejected and restApi.workflowsGet to locate where to add this check and
error construction.

In
`@portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 1063-1080: The current conditional hides MUIDataTable when
filteredData.length === 0 which prevents MUIDataTable from showing its
configured no-match message (textLabels.body.noMatch); instead, always render
<MUIDataTable ... data={filteredData} ... /> when filteredData is defined
(including empty arrays) and remove the separate "No items yet" block, or change
the external empty-state check to use the original unfiltered dataset (e.g., the
source data variable) so that the table handles empty search results via its
options/textLabels and the standalone Typography fallback only appears when
there is no source data at all.
- Around line 269-295: The code currently ignores any rejected Promise from
Promise.allSettled and returns a partial workflowList; change the handling in
the Promise.allSettled().then block so that if any result has status ===
'rejected' you surface an error (or at minimum log/warn with details) instead of
silently proceeding: inspect results alongside the original types array to map
failures to their corresponding workflow type, build an aggregated Error (or
call process/logger) containing the failed type names and reason(s) from the
rejected entries, and then either throw that Error (to stop and surface the
problem) or return both the successful workflows and a visible warning flag;
update the block around workflowsGet, results, and the return of workflowList to
include this check and use the rejected[i].reason and types[i] to produce
actionable messages.
- Around line 456-470: visibleKeys is only built from row.simpleProperties so
rows whose payload is entirely nested (no simpleProperties) end up with no
visible columns (hiding the identifier/description); update the visibleKeys
useMemo to also consider a fallback identifier column by: when iterating
filteredData include top-level keys (e.g., row.description or other non-simple
keys) into the keys set if simpleProperties is empty or missing, ensure
"description" is always added when present, and then apply the same
sorting/slicing logic (symbols to edit: visibleKeys, filteredData,
simpleProperties, description, DEFAULT_MAX_COLUMNS_INCLUDING_ACTION,
toTitleCase). Ensure the computed maxSimple and the final slice behavior remain
unchanged.
- Around line 627-630: In WorkflowApprovalTasks.jsx the entries.map rendering
uses toText(...) for both keys and values so nested objects/arrays get
stringified; change the value cell rendering (inside entries.map -> TableCell)
to detect arrays/objects and delegate to the same dynamic
renderer/structured-table component used elsewhere instead of always calling
toText — e.g. replace toText(v) with a conditional that returns the
StructuredTable (or the file’s existing dynamic render function) for
objects/arrays and toText(v) for primitives; apply the same change to the other
structured-table branch around the other entries.map usage so nested payloads
(e.g. config.endpoints or [{changes:...}]) keep their nested structure.

---

Duplicate comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx`:
- Around line 456-470: visibleKeys is built only from row.simpleProperties so
rows whose payload is entirely nested render no identifying column (only
Action); modify the visibleKeys computation in WorkflowApprovalTasks.jsx to also
consider a fallback identifier (e.g., include 'description' or the top-level
key(s) from the row when simpleProperties is empty) before slicing to maxSimple;
update the logic that builds keys (the block using filteredData,
simpleProperties, keys Set, sorted, max/maxSimple and
DEFAULT_MAX_COLUMNS_INCLUDING_ACTION) to add the fallback identifier only when
no simple property keys are present so the table always shows an identifier
column.
- Around line 1063-1080: The component is hiding the MUIDataTable when
filteredData is an empty array and showing a static "No items yet" message,
which prevents MUIDataTable from displaying its configured search-empty
textLabels.body.noMatch; remove the conditional branch that replaces the table
when filteredData.length === 0 and instead always render <MUIDataTable> (when
filteredData is defined) passing the filteredData (even if empty) and the
existing options so the table can show its built-in noMatch message; if you need
a different initial-empty message for the unfiltered state, handle that
separately by checking the original data source (not filteredData) before
rendering but do not block the table from rendering on empty filtered results.
- Around line 627-630: The current structured-table rows call toText(...) for
both key and value in entries.map (rendering inside TableRow/TableCell), which
stringifies nested objects/arrays and flattens deeper structure; replace the
toText(v) call (and any toText(...) usages in the other structured-table branch
around the 672-681 block) with the file's dynamic value renderer used elsewhere
(the function/component responsible for rendering nested objects/arrays instead
of JSON strings—e.g., the existing renderDynamicValue/DynamicValue component or
renderValue function in this file), so complex values (objects/arrays) are
passed to that renderer and rendered recursively rather than being
JSON-stringified. Ensure TableCell receives the renderer output instead of a
plain string.

---

Nitpick comments:
In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx`:
- Line 6: The ListLabels component's isAPIProduct prop can be undefined when the
component is rendered without props (e.g., from the API State Change route); add
an explicit default so its intent is clear and to avoid relying on implicit
falsiness—either set a default parameter value in the function signature
(function ListLabels({ isAPIProduct = false }) { ... }) or define a
defaultProps/static default (ListLabels.defaultProps = { isAPIProduct: false })
so isAPIProduct is always boolean when referenced.

In
`@portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx`:
- Around line 10-23: The wrapper repeats generic defaults (helpLink and
maxColumnsIncludingAction={5}) when rendering WorkflowApprovalTasks; refactor by
moving those defaults into the WorkflowApprovalTasks component so wrappers only
pass workflow-specific props. Update WorkflowApprovalTasks to set a default prop
or internal fallback for helpLink (e.g., derived from Configurations.app.docUrl
+ 'consume/manage-application/advanced-topics/workflows/') and for
maxColumnsIncludingAction (default 5), remove these props from wrappers like
ApplicationCreation.jsx, and ensure existing callers still override them when
needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cb73f1ff-608e-4d5e-a4d1-ad7c9014e866

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7e210 and bf3faec.

📒 Files selected for processing (17)
  • portals/admin/src/main/webapp/site/public/locales/en.json
  • portals/admin/src/main/webapp/site/public/locales/fr.json
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIRevisionDeployment.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/APIStateChange.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/ApplicationUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/RegistrationCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionDeletion.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/SubscriptionUpdate.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/UserCreation.jsx
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionCreation/SubscriptionCreation.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Subscription/SubscriptionUpdate/SubscriptionUpdate.jsx
  • portals/publisher/src/main/webapp/source/src/app/components/Workflow/WorkflowApprovalTasks.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • portals/admin/src/main/webapp/source/src/app/components/Workflow/RegistrationCreation.jsx
  • portals/publisher/src/main/webapp/site/public/locales/en.json

@JanithaSampathBandara JanithaSampathBandara force-pushed the improvement/workflow-executors-dynamic-rendering branch 2 times, most recently from a315120 to 27cbb1c Compare March 10, 2026 09:41
@JanithaSampathBandara JanithaSampathBandara force-pushed the improvement/workflow-executors-dynamic-rendering branch from 27cbb1c to 6d6433d Compare March 10, 2026 13:12
@tharikaGitHub
Copy link
Copy Markdown
Member

@JanithaSampathBandara shall we add some screenshots of the UI as well to the PR description?

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
81.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@JanithaSampathBandara
Copy link
Copy Markdown
Author

@JanithaSampathBandara shall we add some screenshots of the UI as well to the PR description?

Added few samples in the PR description

@PasanT9 PasanT9 merged commit f585d4f into wso2:main Mar 13, 2026
2 of 4 checks passed
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.

4 participants