Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import { injectIntl } from 'react-intl';
import API from 'AppData/api';
import MCPServer from 'AppData/MCPServer';
import Subscription from 'AppData/Subscription';
import CONSTANTS from 'AppData/Constants';
import NoApi from 'AppComponents/Apis/Listing/NoApi';
import Loading from 'AppComponents/Base/Loading/Loading';
Expand Down Expand Up @@ -82,8 +83,8 @@
* @param {JSON} prevProps props from previous component instance
*/
componentDidUpdate(prevProps) {
const { subscriptions, searchText } = this.props;
if (subscriptions.length !== prevProps.subscriptions.length) {
const { refreshKey, searchText } = this.props;
if (refreshKey !== prevProps.refreshKey) {
this.getData();
} else if (searchText !== prevProps.searchText) {
this.page = 0;
Expand All @@ -101,7 +102,9 @@
const { list, pagination } = body;
const { total } = pagination;
this.count = total;
this.setState({ data: this.updateUnsubscribedAPIsList(list) });
return this.resolveSubscribedIds(list).then((subscribedIds) => {
this.setState({ data: this.updateUnsubscribedAPIsList(list, subscribedIds) });
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})
.catch((error) => {
const { response } = error;
Expand All @@ -125,20 +128,29 @@
};

/**
* Resolve which entities in the given page are already subscribed by this application.
*
* Get List of the Ids of all APIs that have been already subscribed
*
* @returns {*} Ids of respective APIs
* @param {Array} list a page of APIs or MCP Servers
* @returns {Promise<Set<string>>} ids of the entities in this page that are already subscribed
* @memberof APICardView
*/
getIdsOfSubscribedEntities() {
const { subscriptions } = this.props;

// Get arrays of the API Ids and remove all null/empty references by executing 'fliter(Boolean)'
const subscribedAPIIds = subscriptions.map((sub) => sub.apiId).filter(Boolean);

return subscribedAPIIds;
}
resolveSubscribedIds = (list) => {
const { applicationId } = this.props;
const subscribedIds = new Set();
if (!applicationId || !list || list.length === 0) {
return Promise.resolve(subscribedIds);
}
const client = new Subscription();
return Promise.all(list.map((entity) => client.getSubscriptions(entity.id, applicationId, 1, 0)
.then((response) => {
const subList = (response && response.body && response.body.list) || [];

Check warning on line 146 in portals/devportal/src/main/webapp/source/src/app/components/Apis/Listing/APICardView.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=wso2_apim-apps&issues=AZ_L-fvYpAlu9Xgqbu58&open=AZ_L-fvYpAlu9Xgqbu58&pullRequest=1410
if (subList.length > 0) {
subscribedIds.add(entity.id);
}
})
.catch(() => {})))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
.then(() => subscribedIds);
};

changePage = (page) => {
const { intl, entityType } = this.props;
Expand All @@ -149,8 +161,10 @@
.then((data) => {
const { body } = data;
const { list } = body;
this.setState({
data: this.updateUnsubscribedAPIsList(list),
return this.resolveSubscribedIds(list).then((subscribedIds) => {
this.setState({
data: this.updateUnsubscribedAPIsList(list, subscribedIds),
});
});
})
.catch(() => {
Expand Down Expand Up @@ -194,15 +208,14 @@
* @returns {Array} filtered list of apis
* @memberof APICardView
*/
updateUnsubscribedAPIsList(list) {
const subscribedIds = this.getIdsOfSubscribedEntities();
updateUnsubscribedAPIsList(list, subscribedIds) {
const listLocal = list.filter((api) => !(api.throttlingPolicies.length === 1
&& api.throttlingPolicies[0].includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)));
for (let i = 0; i < listLocal.length; i++) {
const policyList = listLocal[i].throttlingPolicies
.filter((policy) => !policy.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN));
listLocal[i].throttlingPolicies = policyList;
if (!((!subscribedIds.includes(listLocal[i].id) && !listLocal[i].advertiseInfo.advertised)
if (!((!subscribedIds.has(listLocal[i].id) && !listLocal[i].advertiseInfo.advertised)
&& listLocal[i].isSubscriptionAvailable)) {
listLocal[i].throttlingPolicies = null;
}
Expand Down Expand Up @@ -389,7 +402,7 @@
intl: PropTypes.shape({
formatMessage: PropTypes.func,
}).isRequired,
subscriptions: PropTypes.arrayOf(PropTypes.shape({})),
refreshKey: PropTypes.number,
searchText: PropTypes.string,
handleSubscribe: PropTypes.func.isRequired,
applicationId: PropTypes.string.isRequired,
Expand All @@ -399,7 +412,7 @@
};

APICardView.defaultProps = {
subscriptions: [],
refreshKey: 0,
searchText: '',
apisNotFound: false,
setTenantDomain: () => {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ class SubscriptionsBase extends React.Component {
pseudoMcpSubscriptions: false,
dialogSubscriptions: null,
dialogMcpSubscriptions: null,
dialogRefreshKey: 0,
dialogMcpRefreshKey: 0,
};
this.checkSubValidationDisabled = this.checkSubValidationDisabled.bind(this);
this.checkMcpSubValidationDisabled = this.checkMcpSubValidationDisabled.bind(this);
Expand Down Expand Up @@ -302,8 +304,6 @@ class SubscriptionsBase extends React.Component {
this.searchTextTmp = '';
this.mounted = false;
this.subscriptionsRequestId = 0;
this.dialogLoadRequestId = 0;
this.mcpDialogLoadRequestId = 0;

this.resetAccumulation();
}
Expand All @@ -325,8 +325,6 @@ class SubscriptionsBase extends React.Component {
componentWillUnmount() {
this.mounted = false;
this.subscriptionsRequestId += 1;
this.dialogLoadRequestId += 1;
this.mcpDialogLoadRequestId += 1;
}

handleOpenDialog() {
Expand Down Expand Up @@ -560,23 +558,23 @@ class SubscriptionsBase extends React.Component {
}

/**
* Update the full, unpaginated list backing a subscribe dialog (API or MCP).
* Refresh the contents of a subscribe dialog (API or MCP).
* @param {boolean} isMcp whether this is refreshing the MCP Server dialog
* @returns {Promise<void>}
* @memberof Subscriptions
*/
updateDialogSubscriptions(isMcp) {
const requestId = isMcp ? ++this.mcpDialogLoadRequestId : ++this.dialogLoadRequestId;
return this.ensureLoaded(Infinity, Infinity).then(() => {
const currentRequestId = isMcp ? this.mcpDialogLoadRequestId : this.dialogLoadRequestId;
const dialogOpen = isMcp ? this.state.openMcpDialog : this.state.openDialog;
if (!this.mounted || requestId !== currentRequestId || !dialogOpen) {
return;
}
const filtered = this.combinedSubscriptions.filter(isMcp ? isMcpSubscription : isApiSubscription);
this.setState(isMcp ? { dialogMcpSubscriptions: filtered } : { dialogSubscriptions: filtered });
this.refreshDerivedState();
});
// APICardView resolves subscription status per page, so the full list is not needed here.
// The empty array makes the dialog render the card view rather than the spinner, and the
// refresh key triggers a reload in APICardView.
const dialogOpen = isMcp ? this.state.openMcpDialog : this.state.openDialog;
if (!this.mounted || !dialogOpen) {
return Promise.resolve();
}
this.setState((prevState) => (isMcp
? { dialogMcpSubscriptions: [], dialogMcpRefreshKey: prevState.dialogMcpRefreshKey + 1 }
: { dialogSubscriptions: [], dialogRefreshKey: prevState.dialogRefreshKey + 1 }));
return Promise.resolve();
}

/**
Expand Down Expand Up @@ -841,6 +839,8 @@ class SubscriptionsBase extends React.Component {
pseudoMcpSubscriptions,
dialogSubscriptions,
dialogMcpSubscriptions,
dialogRefreshKey,
dialogMcpRefreshKey,
} = this.state;

if (!isAuthorize) {
Expand Down Expand Up @@ -1054,8 +1054,8 @@ class SubscriptionsBase extends React.Component {
{dialogSubscriptions ? (
<APIList
apisNotFound={apisNotFound}
subscriptions={dialogSubscriptions}
applicationId={applicationId}
refreshKey={dialogRefreshKey}
handleSubscribe={(appInner, api, policy) => this.handleSubscribe(appInner, api, policy)}
searchText={searchText}
entityType='API'
Expand Down Expand Up @@ -1154,8 +1154,8 @@ class SubscriptionsBase extends React.Component {
{dialogMcpSubscriptions ? (
<APIList
apisNotFound={apisNotFound}
subscriptions={dialogMcpSubscriptions}
applicationId={applicationId}
refreshKey={dialogMcpRefreshKey}
handleSubscribe={(appInner, api, policy) => this.handleSubscribe(appInner, api, policy)}
searchText={searchText}
entityType='MCP'
Expand Down
Loading