Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughDetects AsyncAPI v3 and adds end-to-end v3 support: channel↔component mapping, named operations, v3-specific UI/validation for operations and payloads, persistence transform for v3 specs, new Async v3 operations list component, localization entries, and theme colors for send/receive verbs. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Topics as Topics Component
participant Spec as Spec Loader/Resolver
participant Mapper as buildChannelMap
participant UI as AddOperation/AsyncOperation
participant Rebuilder as rebuildOperations
participant Storage as Spec Save
User->>Topics: Open API details / edit
Topics->>Spec: Fetch & resolve AsyncAPI
Spec-->>Topics: Return spec (includes version)
Topics->>Topics: Set isAsyncV3 flag
alt AsyncAPI v3
Topics->>Mapper: buildChannelMap(spec)
Mapper-->>Topics: channel-centric map + namedOperations
Topics->>UI: render with isAsyncV3 & namedOperations
User->>UI: Add/Edit named operation or payload
UI->>Topics: Dispatch changes
Topics->>Rebuilder: rebuildOperations(channelMap, origSpec)
Rebuilder-->>Topics: transformed v3 spec (components/messages)
Topics->>Storage: Save rebuilt spec
else Legacy AsyncAPI
Topics->>UI: render legacy channels/verbs
User->>UI: Add/Edit operation
UI->>Topics: Dispatch channel updates
Topics->>Storage: Save channels-based spec
end
Storage-->>User: Save confirmation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/PayloadProperties.jsx (1)
85-100:⚠️ Potential issue | 🟡 MinorMissing
isAsyncV3in propTypes.The
isAsyncV3prop is destructured and used (lines 41, 64, 78) but not declared inpropTypes. This will cause PropTypes warnings in development.🐛 Proposed fix
PayloadProperties.propTypes = { target: PropTypes.string.isRequired, verb: PropTypes.string.isRequired, spec: PropTypes.shape({}).isRequired, operationsDispatcher: PropTypes.func.isRequired, operation: PropTypes.shape({}).isRequired, disableUpdate: PropTypes.bool, resolvedSpec: PropTypes.shape({}).isRequired, disableForSolace: PropTypes.bool, namedOperations: PropTypes.arrayOf(PropTypes.string), + isAsyncV3: PropTypes.bool, }; PayloadProperties.defaultProps = { disableUpdate: false, disableForSolace: false, namedOperations: [], + isAsyncV3: false, };🤖 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/Apis/Details/Resources/components/operationComponents/asyncapi/PayloadProperties.jsx` around lines 85 - 100, The component is missing the isAsyncV3 entry in its prop type declarations; add isAsyncV3: PropTypes.bool.isRequired or PropTypes.bool (matching intended usage) to PayloadProperties.propTypes and include a matching default in PayloadProperties.defaultProps (e.g., isAsyncV3: false) so the destructured prop used in PayloadProperties (referenced at lines where isAsyncV3 is read) is properly declared and has a default value.portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx (1)
698-745:⚠️ Potential issue | 🔴 CriticalKeep the channel cleanup verb-aware for AsyncAPI v3.
In this save path, the deletion cleanup at the top of
updateAsyncAPI()still only checkspublish/subscribe. For v3, removing justsendorreceivemakes that condition true immediately, so the entire channel is deleted and any sibling action on the same channel is lost.💡 Suggested fix
for (const [target, verbs] of Object.entries(markedOperations)) { for (const verb of Object.keys(verbs)) { delete copyOfOperations[target][verb]; - if (!copyOfOperations[target].publish && !copyOfOperations[target].subscribe) { + const remainingVerbs = isAsyncV3 ? ['send', 'receive'] : ['publish', 'subscribe']; + if (remainingVerbs.every((candidate) => !copyOfOperations[target]?.[candidate])) { delete copyOfOperations[target]; } } }🤖 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/Apis/Details/Configuration/Topics.jsx` around lines 698 - 745, The cleanup loop in updateAsyncAPI currently deletes channel verbs and then unconditionally checks only publish/subscribe, which for AsyncAPI v3 (where verbs are send/receive) causes sibling actions to be lost; update the loop that iterates markedOperations/verb (in updateAsyncAPI, using cloneDeep(operations), markedOperations, copyOfOperations) to be verb-aware based on isAsyncV3: determine the relevant action keys (e.g., const actionKeys = isAsyncV3 ? ['send','receive'] : ['publish','subscribe']) and after deleting copyOfOperations[target][verb] check that none of the actionKeys remain on copyOfOperations[target] before deleting the whole channel; this preserves sibling actions for AsyncAPI v3 and V2 while keeping the existing rebuildOperations/isAsyncV3 flow intact.
🧹 Nitpick comments (2)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx (1)
1-14: Missing copyright header.This new file is missing the standard WSO2 copyright header that other files in this codebase include. Consider adding it for consistency.
📝 Suggested addition at the top of the file
+/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import React from 'react';🤖 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/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx` around lines 1 - 14, This file Asyncv3OperationsList.jsx is missing the repository's standard WSO2 copyright header; add the exact standard header block used across the project to the very top of Asyncv3OperationsList.jsx (above the React imports) so it matches other files for licensing and consistency.portals/publisher/src/main/webapp/site/public/locales/en.json (1)
1634-1639: Remove the duplicatedAsyncOperation.*locale keys.
Apis.Details.Resources.components.AsyncOperation.no.security,security.enabled, andsecurity.operationare already declared a few lines above. Keeping both copies works only because the later entries silently override the earlier ones, which makes future translation changes easy to miss.🤖 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 1634 - 1639, Remove the duplicated AsyncOperation locale entries by deleting the repeated keys "Apis.Details.Resources.components.AsyncOperation.no.security", "Apis.Details.Resources.components.AsyncOperation.security.enabled", and "Apis.Details.Resources.components.AsyncOperation.security.operation" from this block so only the original definitions remain; locate these duplicate keys in the en.json snippet around the AsyncOperation entries (the originals appear a few lines above) and remove the later overrides to prevent silent replacement and translation drift.
🤖 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/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 474-479: In the deleteNamedOperation branch in Topics.jsx (case
'deleteNamedOperation') you only remove the operation name from
channelCopy[verb]['x-operations'] but must also prune any payload property
metadata that references that operation; update the code to traverse
channelCopy[verb].message.payload.properties (and nested schemas) and remove or
clear any 'x-operation' (or 'x-operation(s)') entries equal to value so
rebuildOperations() won't recreate the payload model, and mirror the same
cleanup in the other similar handler (the block around the earlier 239-277 area)
to ensure named-operation references are fully removed before returning the
updated currentOperations object.
- Around line 240-254: The forEach over byMessage destructures the wrong
key—currently using { opName, prop }—so
newComponents.schemas[msgName].properties gets undefined; change the
destructuring to { opName, props } and use that props map when building the
schema (i.e., set properties to props) so the rebuilt AsyncAPI schemas retain
edited payload fields; locate the loop iterating Object.entries(byMessage) and
update the destructure and usage accordingly (symbols: byMessage, props, opName,
newComponents.schemas).
- Around line 128-143: The code uses the raw channel ref string (chRef -> chKey)
to look up spec.channels, but JSON Pointer escaping (˜1 for "/" and ˜0 for "~")
means keys like "#/channels/foo~1bar" won't match; decode the pointer segment
before indexing: extract the channel token from chRef as you do now, then
unescape by replacing "~1" with "/" and "~0" with "~" to produce a decoded key,
and use that decoded key when accessing spec.channels (and when comparing
against any channelIndex). Update references to chKey in this block (the
variables chRef, chKey, and the lookup into spec.channels/channelSpecObj) to use
the decoded key.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsx`:
- Around line 116-122: When isAsyncV3 is true the computed target (derived from
channelItem.address) can be undefined and later used to index api.operations or
compared in PoliciesExpansion; update the logic in PoliciesSection (the block
computing operation and target) to defensively handle missing address by falling
back to channelName or by skipping/returning early when neither address nor
channelName exist, and ensure downstream consumers (OperationPolicy and
PoliciesExpansion checks using api.operations[target] and op.target === target)
are only executed when target is a defined string.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx`:
- Around line 376-384: The mapped VerbElement inside the Select lacks a React
key, causing reconciliation warnings; update the map callback in the component
rendering getSupportedVerbs() to pass a stable key prop to <VerbElement> (for
example use the lower-cased verb value such as verb.toLowerCase() or
`${verb.toLowerCase()}`; if duplicates are possible use a combination like
`${verb.toLowerCase()}-${index}`) so the elements rendered from
getSupportedVerbs().map(...) have unique keys that reference the verb value.
- Around line 243-296: The three functions getOperationLabel,
getOperationPlaceholder, and getOperationHelpertext contain duplicate if
(isAsyncAPI) checks so the second branch is unreachable; change the first
condition to check for isAsyncV3 && isAsyncAPI (to return the Channel Address
strings) and keep the second as isAsyncAPI (to return Topic Name strings),
leaving the final fallback to the URI Pattern; update all three functions
consistently and ensure they reference isAsyncV3 and isAsyncAPI in that order so
the correct message IDs/defaultMessages are returned.
- Line 334: In the AddOperation.jsx component, remove the obsolete
getContentAnchorEl property from any MenuProps objects (e.g., the JSX where
MenuProps={{ getContentAnchorEl: null }} is used) because MUI v5 removed that
prop; update the MenuProps to omit getContentAnchorEl entirely (e.g., change
MenuProps={{ getContentAnchorEl: null }} to simply MenuProps={{}} or remove the
MenuProps prop if empty) and apply the same change to the other occurrence noted
in the file.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx`:
- Line 274: The Badge usage in AsyncOperation.jsx passes the invisible prop as a
string ("false") which is incorrect; update the Badge element (Badge) to pass a
boolean value instead (e.g., invisible={false}) or remove the prop if you want
the default visible behavior so the prop type is boolean rather than string.
- Line 186: In the AsyncOperation component update the Badge usage: the
invisible prop is currently passed as a string ("false") which is truthy; change
the prop on the Badge element (Badge invisible='false' ...) to pass a boolean
(invisible={false}) so the dot remains visible; keep the existing color and
variant props unchanged.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx`:
- Around line 80-90: The switch handling in AddPayloadProperty.jsx currently
breaks for the 'name' and 'description' cases, preventing updates to nextState
and stopping the inputs from updating; modify the 'name' and 'description' cases
in the switch (inside the AddPayloadProperty component/function where nextState
and value are used) to assign the new value (e.g., nextState[type] = value)
instead of breaking so that typing updates the component state; keep the V3-only
guards for 'operation' and 'message' as-is.
---
Outside diff comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 698-745: The cleanup loop in updateAsyncAPI currently deletes
channel verbs and then unconditionally checks only publish/subscribe, which for
AsyncAPI v3 (where verbs are send/receive) causes sibling actions to be lost;
update the loop that iterates markedOperations/verb (in updateAsyncAPI, using
cloneDeep(operations), markedOperations, copyOfOperations) to be verb-aware
based on isAsyncV3: determine the relevant action keys (e.g., const actionKeys =
isAsyncV3 ? ['send','receive'] : ['publish','subscribe']) and after deleting
copyOfOperations[target][verb] check that none of the actionKeys remain on
copyOfOperations[target] before deleting the whole channel; this preserves
sibling actions for AsyncAPI v3 and V2 while keeping the existing
rebuildOperations/isAsyncV3 flow intact.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/PayloadProperties.jsx`:
- Around line 85-100: The component is missing the isAsyncV3 entry in its prop
type declarations; add isAsyncV3: PropTypes.bool.isRequired or PropTypes.bool
(matching intended usage) to PayloadProperties.propTypes and include a matching
default in PayloadProperties.defaultProps (e.g., isAsyncV3: false) so the
destructured prop used in PayloadProperties (referenced at lines where isAsyncV3
is read) is properly declared and has a default value.
---
Nitpick comments:
In `@portals/publisher/src/main/webapp/site/public/locales/en.json`:
- Around line 1634-1639: Remove the duplicated AsyncOperation locale entries by
deleting the repeated keys
"Apis.Details.Resources.components.AsyncOperation.no.security",
"Apis.Details.Resources.components.AsyncOperation.security.enabled", and
"Apis.Details.Resources.components.AsyncOperation.security.operation" from this
block so only the original definitions remain; locate these duplicate keys in
the en.json snippet around the AsyncOperation entries (the originals appear a
few lines above) and remove the later overrides to prevent silent replacement
and translation drift.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx`:
- Around line 1-14: This file Asyncv3OperationsList.jsx is missing the
repository's standard WSO2 copyright header; add the exact standard header block
used across the project to the very top of Asyncv3OperationsList.jsx (above the
React imports) so it matches other files for licensing and consistency.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 62a4bcb4-0eb0-4203-a837-5fee48188c81
📒 Files selected for processing (11)
portals/devportal/src/main/webapp/source/src/app/data/defaultTheme.jsportals/publisher/src/main/webapp/site/public/locales/en.jsonportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/ListPayloadProperties.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/PayloadProperties.jsxportals/publisher/src/main/webapp/source/src/app/data/defaultTheme.js
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Outdated
Show resolved
Hide resolved
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Outdated
Show resolved
Hide resolved
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Show resolved
Hide resolved
...ublisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsx
Show resolved
Hide resolved
...src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx
Show resolved
Hide resolved
...src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx
Outdated
Show resolved
Hide resolved
...src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx
Show resolved
Hide resolved
...c/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx
Outdated
Show resolved
Hide resolved
...c/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx
Outdated
Show resolved
Hide resolved
...onents/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx
Show resolved
Hide resolved
...onents/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx
Outdated
Show resolved
Hide resolved
...nts/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx
Show resolved
Hide resolved
...src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx (1)
365-373:⚠️ Potential issue | 🟠 MajorBulk security toggle does not persist for AsyncAPI v3 operations.
This reducer still mutates
newChannel['x-auth-type'], butrebuildOperations()serializesverbInfo['x-auth-type']fromsend/receive. For v3, the toolbar toggle can appear to work while the saved spec stays unchanged.Possible fix
case 'toggleSecurityStatus': setSelectedOperation({}); return Object.entries(currentOperations).reduce((channelAcc, [channelKey, channelObj]) => { const newChannel = { ...channelObj }; - newChannel['x-auth-type'] = data.disable ? 'None' : 'Any'; + if (isAsyncV3) { + ['send', 'receive'].forEach((actionKey) => { + if (newChannel[actionKey]) { + newChannel[actionKey] = { + ...newChannel[actionKey], + 'x-auth-type': data.disable ? 'None' : 'Any', + }; + } + }); + } else { + newChannel['x-auth-type'] = data.disable ? 'None' : 'Any'; + } const newChannelAcc = { ...channelAcc }; newChannelAcc[channelKey] = newChannel; return newChannelAcc; }, {});🤖 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/Apis/Details/Configuration/Topics.jsx` around lines 365 - 373, The toggleSecurityStatus reducer is mutating channel-level x-auth-type which doesn't persist for AsyncAPI v3 because rebuildOperations() reads verbInfo['x-auth-type'] from operation objects (send/receive); update the reducer (case 'toggleSecurityStatus') to immutably set x-auth-type on each operation object inside channelObj (e.g., newChannel.send['x-auth-type'] and/or newChannel.receive['x-auth-type'] depending on presence) based on data.disable, rather than setting newChannel['x-auth-type'], so rebuildOperations() will serialize the change; keep using currentOperations and ensure you create new objects for channel, send, and receive to avoid mutation.
♻️ Duplicate comments (2)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx (1)
476-481:⚠️ Potential issue | 🟠 MajorNamed-operation delete is still leaving stale payload metadata behind.
This only removes the name from
x-operations. Properties that still carryx-operation: valueremain undermessage.payload.properties, andrebuildOperations()continues to emit message/schema entries from them on save.🤖 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/Apis/Details/Configuration/Topics.jsx` around lines 476 - 481, In the deleteNamedOperation case (inside the reducer handling currentOperations/channelCopy and the verb entry), after filtering channelCopy[verb]['x-operations'], also remove any per-property metadata that references the deleted operation name: iterate channelCopy[verb].message.payload.properties (and nested schema entries if present) and delete or unset any property['x-operation'] equal to value so rebuildOperations() won't see stale x-operation markers; update the logic in the same deleteNamedOperation branch to perform this cleanup before returning { ...currentOperations, [target]: channelCopy } and ensure you handle missing message/payload/properties safely.portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx (1)
349-352:⚠️ Potential issue | 🟡 MinorAdd keys at the
map()call sites, not insideVerbElement.The
keyonListItemdoes not satisfy the outerverbs.map(...)/getSupportedVerbs().map(...). Biome is already flagging the menu branch, and the renderValue branch has the same reconciliation issue.Also applies to: 375-380
🤖 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/Apis/Details/Resources/components/AddOperation.jsx` around lines 349 - 352, The outer array maps (verbs.map and the getSupportedVerbs().map used for the menu/renderValue branches) are missing stable keys at the map return sites; move/add key props to the elements returned by those map callbacks (e.g., when returning <VerbElement ... /> from verbs.map and when returning the ListItem/menu items from getSupportedVerbs().map and the renderValue branch) instead of relying on a key inside VerbElement or inside children; use a stable unique value such as verb or `${verb}-${index}` for the key to ensure correct reconciliation.
🤖 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/publisher/src/main/webapp/site/public/locales/en.json`:
- Around line 1634-1639: Remove the duplicated AsyncOperation translation
entries so there is only one declaration for each key; locate the repeated keys
like "Apis.Details.Resources.components.AsyncOperation.delete",
"Apis.Details.Resources.components.AsyncOperation.no.operations",
"Apis.Details.Resources.components.AsyncOperation.no.security",
"Apis.Details.Resources.components.AsyncOperation.operations.count.label",
"Apis.Details.Resources.components.AsyncOperation.security.enabled" and
"Apis.Details.Resources.components.AsyncOperation.security.operation" and delete
the second set (keep the original definitions) to prevent later entries from
shadowing earlier translations.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 153-159: The current flattening in Topics.jsx that writes into
allProperties using the raw propName (seen in the Object.entries loop) causes
collisions when different messages share field names; change the map key
strategy so properties are namespaced by operation and message (e.g., include
opName and msgKey in the key) or store properties in a nested structure keyed
first by operation and message before propName, and apply the same change to the
duplicate block at the other location referenced (lines 489-495) so fields from
different messages do not overwrite each other during load/edit and the AsyncAPI
v3 round-trip preserves all data.
- Around line 186-223: rebuildOperations currently seeds newChannels from
originalSpec.channels which preserves channels deleted in the UI; change the
logic in rebuildOperations (and the channel-merging block that processes
channelMap) to start from an empty newChannels (do not copy
originalSpec.channels) and only add a channel when the channelObj in channelMap
actually has operations (publish/subscribe or send/receive) — for
existingChannelName cases, if channelObj has no operations, remove/skip
newChannels[existingChannelName]; also tighten the parameters check (use
Array.isArray(parametersArray) && parametersArray.length > 0) when adding
parameters so empty arrays aren’t persisted; these changes in rebuildOperations
and the channelMap merge will ensure buildChannelMap() does not resurrect empty
channels on reload.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx`:
- Around line 104-109: The backgroundColor lookup uses the raw verb which causes
v2 verbs like 'publish'/'subscribe' to miss theme keys; change the lookup to use
trimmedVerb instead of verb (i.e., replace theme.custom.resourceChipColors[verb]
with theme.custom.resourceChipColors[trimmedVerb]) where backgroundColor is
computed in AsyncOperation.jsx (the trimmedVerb constant and backgroundColor
assignment near useTheme()). Ensure the fallback to theme.palette.primary.main
remains unchanged.
- Around line 242-267: The Tooltip/Icon logic in AsyncOperation.jsx is reading
operation['x-auth-type'] directly, but for AsyncAPI v3 the selected action's
auth is stored in currentOperations[target][verb]; update the auth check to
first read the x-auth-type from the selected v3 action (e.g. const selectedOp =
currentOperations?.[target]?.[verb]) and use selectedOp['x-auth-type'] (falling
back to operation['x-auth-type'] if selectedOp is undefined) when deciding which
FormattedMessage and icon (LockIcon/LockOpenIcon) to render; adjust the Tooltip
title and the ternary that picks the icon to use this unified auth value so
send/receive rows configured as None render correctly.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx`:
- Around line 128-138: In addNewProperty, ensure that for AsyncAPI v3 you
require both property.operation and property.message to be non-empty before
dispatching: if isAsyncV3 and either property.operation or property.message is
falsy, call Alert.error with a localized message and return (instead of only
rejecting unknown non-empty operation); also keep the existing check that if
operation is present it must be in namedOperations. Apply the same guard to the
other v3 dispatch path in this file (the similar block around the later dispatch
between the 150-195 region) so rebuildOperations() cannot bucket empty
operation/message values under "__default__".
---
Outside diff comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 365-373: The toggleSecurityStatus reducer is mutating
channel-level x-auth-type which doesn't persist for AsyncAPI v3 because
rebuildOperations() reads verbInfo['x-auth-type'] from operation objects
(send/receive); update the reducer (case 'toggleSecurityStatus') to immutably
set x-auth-type on each operation object inside channelObj (e.g.,
newChannel.send['x-auth-type'] and/or newChannel.receive['x-auth-type']
depending on presence) based on data.disable, rather than setting
newChannel['x-auth-type'], so rebuildOperations() will serialize the change;
keep using currentOperations and ensure you create new objects for channel,
send, and receive to avoid mutation.
---
Duplicate comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 476-481: In the deleteNamedOperation case (inside the reducer
handling currentOperations/channelCopy and the verb entry), after filtering
channelCopy[verb]['x-operations'], also remove any per-property metadata that
references the deleted operation name: iterate
channelCopy[verb].message.payload.properties (and nested schema entries if
present) and delete or unset any property['x-operation'] equal to value so
rebuildOperations() won't see stale x-operation markers; update the logic in the
same deleteNamedOperation branch to perform this cleanup before returning {
...currentOperations, [target]: channelCopy } and ensure you handle missing
message/payload/properties safely.
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsx`:
- Around line 349-352: The outer array maps (verbs.map and the
getSupportedVerbs().map used for the menu/renderValue branches) are missing
stable keys at the map return sites; move/add key props to the elements returned
by those map callbacks (e.g., when returning <VerbElement ... /> from verbs.map
and when returning the ListItem/menu items from getSupportedVerbs().map and the
renderValue branch) instead of relying on a key inside VerbElement or inside
children; use a stable unique value such as verb or `${verb}-${index}` for the
key to ensure correct reconciliation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 66ec7d68-a33e-4dde-853c-35db290afb66
📒 Files selected for processing (8)
portals/publisher/src/main/webapp/site/public/locales/en.jsonportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AddOperation.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/ListPayloadProperties.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
- portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsx
- portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/ListPayloadProperties.jsx
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Outdated
Show resolved
Hide resolved
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Outdated
Show resolved
Hide resolved
...c/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx
Outdated
Show resolved
Hide resolved
...c/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx
Outdated
Show resolved
Hide resolved
...onents/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx (1)
729-731:⚠️ Potential issue | 🟠 MajorV3 channels not cleaned up when last send/receive operation is deleted.
The cleanup logic checks for
publishandsubscribeverbs, but for AsyncAPI v3, the verbs aresendandreceive. When deleting operations in v3 mode, empty channels won't be pruned fromcopyOfOperations.🐛 Proposed fix
for (const [target, verbs] of Object.entries(markedOperations)) { for (const verb of Object.keys(verbs)) { delete copyOfOperations[target][verb]; - if (!copyOfOperations[target].publish && !copyOfOperations[target].subscribe) { + const hasV2Ops = copyOfOperations[target].publish || copyOfOperations[target].subscribe; + const hasV3Ops = copyOfOperations[target].send || copyOfOperations[target].receive; + if (!hasV2Ops && !hasV3Ops) { delete copyOfOperations[target]; } } }🤖 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/Apis/Details/Configuration/Topics.jsx` around lines 729 - 731, The cleanup only checks publish/subscribe so channels using AsyncAPI v3 verbs remain; update the channel-pruning logic that inspects copyOfOperations to also treat send and receive as equivalent to publish/subscribe (i.e., delete copyOfOperations[target] when neither publish nor subscribe nor send nor receive exist). Locate the block referencing copyOfOperations[target].publish and .subscribe in Topics.jsx and extend the condition to include .send and .receive so empty AsyncAPI v3 channels are removed.
♻️ Duplicate comments (4)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx (3)
186-186:⚠️ Potential issue | 🟡 MinorIncorrect prop type:
invisibleshould be a boolean.
invisible='false'passes a string"false", which is truthy and will hide the Badge dot. Useinvisible={false}instead.🐛 Proposed fix
-<Badge invisible='false' color='error' variant='dot'> +<Badge invisible={false} color='error' variant='dot'>🤖 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/Apis/Details/Resources/components/AsyncOperation.jsx` at line 186, In the AsyncOperation component update the Badge prop so the invisible prop is a boolean, not a string: change the Badge usage (Badge invisible='false' ...) to pass a boolean (invisible={false}) so the dot remains visible; locate the Badge element in AsyncOperation.jsx and replace the string prop with the boolean expression.
274-274:⚠️ Potential issue | 🟡 MinorSame issue:
invisibleprop should be boolean.🐛 Proposed fix
-<Badge invisible='false' color='error' variant='dot'> +<Badge invisible={false} color='error' variant='dot'>🤖 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/Apis/Details/Resources/components/AsyncOperation.jsx` at line 274, In AsyncOperation.jsx the Badge component is passed invisible='false' as a string; change it to a boolean prop (e.g., invisible={false}) so Badge receives a proper boolean value; locate the Badge usage in the AsyncOperation component and update the prop accordingly.
242-267:⚠️ Potential issue | 🟠 MajorV3 branch still reads
x-auth-typefrom the wrong location.For AsyncAPI v3, the auth type is stored at
operation[verb]['x-auth-type'](as set in Topics.jsx reducer lines 394-405), but this code reads fromoperation['x-auth-type']. This causes send/receive rows configured as "None" to incorrectly render as secured.🐛 Proposed fix
+ const v3AuthType = operation[verb]?.['x-auth-type']; + const authTypeValue = isAsyncV3 ? v3AuthType : operation['x-auth-type']; <Tooltip title={ - (!operation['x-auth-type'] || operation['x-auth-type'].toLowerCase() !== 'none') + (!authTypeValue || authTypeValue.toLowerCase() !== 'none') ? ( <FormattedMessage id={'Apis.Details.Resources.components.AsyncOperation.security' + '.enabled'} defaultMessage='Security enabled' /> ) : ( <FormattedMessage id='Apis.Details.Resources.components.AsyncOperation.no.security' defaultMessage='No security' /> ) } > <IconButton aria-label='Security' > - {(!operation['x-auth-type'] || operation['x-auth-type'].toLowerCase() - !== 'none') + {(!authTypeValue || authTypeValue.toLowerCase() !== 'none') ? <LockIcon fontSize='small' /> : <LockOpenIcon fontSize='small' />} </IconButton> </Tooltip>🤖 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/Apis/Details/Resources/components/AsyncOperation.jsx` around lines 242 - 267, The code is reading operation['x-auth-type'] but for AsyncAPI v3 the auth type is nested under the verb (operation[verb]['x-auth-type']), so update the checks in AsyncOperation.jsx (the Tooltip title conditional and the IconButton icon conditional) to read the auth type from operation[verb]['x-auth-type'] (use optional chaining or guard checks like operation[verb] && operation[verb]['x-auth-type']), then apply the same toLowerCase() !== 'none' logic on that value (with a safe fallback) so send/receive rows configured as "None" render unlocked.portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx (1)
153-160:⚠️ Potential issue | 🟠 MajorProperty key collision issue persists in
buildChannelMap.Properties from different messages with the same name will still overwrite each other since
allProperties[propName]uses the raw property name as key. Thex-prop-namemetadata preserves the original name but doesn't prevent loading-time collisions.This was previously flagged and the user indicated it would be corrected, but the current code still uses raw
propNameas the map key.🤖 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/Apis/Details/Configuration/Topics.jsx` around lines 153 - 160, In buildChannelMap the map key allProperties[propName] causes collisions when different messages use the same property name; change the key to a unique composite key (e.g., combine opName, msgKey and propName) when assigning entries so each property is stored separately (update the Object.entries loop that assigns allProperties[...] to use the composite key rather than raw propName while still keeping the x-prop-name metadata).
🧹 Nitpick comments (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx (1)
224-224: Controlled input may receiveundefinedon initial render.
property.namecan beundefinedsince the initial state is{}. This may cause React warnings about switching between controlled and uncontrolled inputs. The v3 fields already use the|| ''fallback pattern (lines 177, 203).♻️ Consistent fallback pattern
-value={property.name} +value={property.name || ''}Apply similarly to
property.type(line 255) andproperty.description(line 300).🤖 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/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx` at line 224, The inputs in AddPayloadProperty.jsx are controlled but may receive undefined because property is initialized as {} — update the JSX value props to use a consistent fallback (e.g., value={property.name || ''}) for the fields currently using property.name, property.type, and property.description so they never pass undefined to the inputs; apply the same || '' pattern used in the v3 fields (lines around 177, 203) to the value attributes in the name, type, and description inputs in the AddPayloadProperty component.
🤖 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/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx`:
- Around line 84-90: aria-label is being set to a React element
(<FormattedMessage>) which must be a string; update the Asyncv3OperationsList
component to convert the message to a string using react-intl's formatter
(useIntl or injectIntl) and replace the FormattedMessage usage in the aria-label
prop with intl.formatMessage({ id:
'Apis.Details.Resources.components.Operation.delete.operation', defaultMessage:
'Delete operation' }); ensure you import and call useIntl (or accept intl via
injectIntl) at the top of the Asyncv3OperationsList function and reference the
formatted string in the aria-label prop instead of the JSX element.
---
Outside diff comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 729-731: The cleanup only checks publish/subscribe so channels
using AsyncAPI v3 verbs remain; update the channel-pruning logic that inspects
copyOfOperations to also treat send and receive as equivalent to
publish/subscribe (i.e., delete copyOfOperations[target] when neither publish
nor subscribe nor send nor receive exist). Locate the block referencing
copyOfOperations[target].publish and .subscribe in Topics.jsx and extend the
condition to include .send and .receive so empty AsyncAPI v3 channels are
removed.
---
Duplicate comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 153-160: In buildChannelMap the map key allProperties[propName]
causes collisions when different messages use the same property name; change the
key to a unique composite key (e.g., combine opName, msgKey and propName) when
assigning entries so each property is stored separately (update the
Object.entries loop that assigns allProperties[...] to use the composite key
rather than raw propName while still keeping the x-prop-name metadata).
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsx`:
- Line 186: In the AsyncOperation component update the Badge prop so the
invisible prop is a boolean, not a string: change the Badge usage (Badge
invisible='false' ...) to pass a boolean (invisible={false}) so the dot remains
visible; locate the Badge element in AsyncOperation.jsx and replace the string
prop with the boolean expression.
- Line 274: In AsyncOperation.jsx the Badge component is passed
invisible='false' as a string; change it to a boolean prop (e.g.,
invisible={false}) so Badge receives a proper boolean value; locate the Badge
usage in the AsyncOperation component and update the prop accordingly.
- Around line 242-267: The code is reading operation['x-auth-type'] but for
AsyncAPI v3 the auth type is nested under the verb
(operation[verb]['x-auth-type']), so update the checks in AsyncOperation.jsx
(the Tooltip title conditional and the IconButton icon conditional) to read the
auth type from operation[verb]['x-auth-type'] (use optional chaining or guard
checks like operation[verb] && operation[verb]['x-auth-type']), then apply the
same toLowerCase() !== 'none' logic on that value (with a safe fallback) so
send/receive rows configured as "None" render unlocked.
---
Nitpick comments:
In
`@portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsx`:
- Line 224: The inputs in AddPayloadProperty.jsx are controlled but may receive
undefined because property is initialized as {} — update the JSX value props to
use a consistent fallback (e.g., value={property.name || ''}) for the fields
currently using property.name, property.type, and property.description so they
never pass undefined to the inputs; apply the same || '' pattern used in the v3
fields (lines around 177, 203) to the value attributes in the name, type, and
description inputs in the AddPayloadProperty component.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6fdc50bf-9d03-423b-aaac-aaf58e9b8bf3
📒 Files selected for processing (7)
portals/publisher/src/main/webapp/site/public/locales/en.jsonportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/AsyncOperation.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/AddPayloadProperty.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsxportals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/ListPayloadProperties.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
- portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesSection.tsx
- portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Resources/components/operationComponents/asyncapi/ListPayloadProperties.jsx
- portals/publisher/src/main/webapp/site/public/locales/en.json
...nts/Apis/Details/Resources/components/operationComponents/asyncapi/Asyncv3OperationsList.jsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx`:
- Around line 665-670: The code reads component state isAsyncV3 (which may be
stale) inside setSecurityDefScopesFromSpec and similar blocks; instead derive
the asyncv3 flag from the computed spec object (the value resolveAndUpdateSpec
sets, e.g. spec.asyncv3 or presence of implicit.availableScopes) before
branching. Update setSecurityDefScopesFromSpec (and the other affected blocks
that reference isAsyncV3) to use a local boolean like const asyncv3 =
!!spec.asyncv3 ||
Boolean(spec.components?.securitySchemes?.oauth2?.flows?.implicit?.availableScopes)
and then use asyncv3 to pick implicitFlow.availableScopes vs implicitFlow.scopes
when calling verifySecurityScheme and setSecurityDefScopes, so you no longer
depend on setIsAsyncV3 timing.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7cba8960-c31b-49cd-a992-331a697b443f
📒 Files selected for processing (1)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
...ls/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/Topics.jsx
Show resolved
Hide resolved
c782edd to
fa987a6
Compare
|
|
@coderabbitai approve |
✅ Actions performedComments resolved. Auto-approval is disabled; enable |



Purpose
$subject
UI changes:
The 'TOPICS' page for an async api (websocket, SSE, websub) will now have another input field to enter the operation name because operations and channels are decoupled in asyncV3. Count of operations in each channel is also displayed.
Operations in each channel is listed inside:
Inside each channel, payload properties addition has been changed to specify to which operation and which message the property needs to be added. In asyncV3, an operation can have multiple messages.
Summary by CodeRabbit
New Features
UI Enhancements
Localization
Style