Skip to content

Commit

Permalink
UI implementation for allowing to have api policy and a common policy…
Browse files Browse the repository at this point in the history
… with same name and same version.

UI fix for wso2/api-manager#3109
  • Loading branch information
RusJaI committed Jan 27, 2025
1 parent 40b148b commit a069d97
Show file tree
Hide file tree
Showing 13 changed files with 418 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@
"Apis.Details.Environments.Environments.status.not.deployed": "No Revision Deployed",
"Apis.Details.Environments.Environments.undeploy.btn": "Undeploy",
"Apis.Details.Environments.Environments.visibility.in.devportal": "Gateway URL Visibility",
"Apis.Details.Environments.Environments.visibility.permission": "Visibility Permission",
"Apis.Details.Environments.Environments.visibility.permission": "Gateway Environment Visibility in Developer Portal.",
"Apis.Details.Environments.deploy.api.gateways.text": "API Gateways",
"Apis.Details.Environments.deploy.env.text": "Deploy API to the Gateway Environment",
"Apis.Details.Environments.deploy.text": "Deploy the API",
Expand Down Expand Up @@ -1173,6 +1173,8 @@
"Apis.Details.Policies.AttachedPolicyForm.General.reset": "Reset",
"Apis.Details.Policies.AttachedPolicyForm.General.save": "Save",
"Apis.Details.Policies.AttachedPolicyForm.General.saving": "Saving",
"Apis.Details.Policies.Components.TabPanel.Components.API.Policy.List": "API Policies",
"Apis.Details.Policies.Components.TabPanel.Components.Common.Policy.List": "Common Policies",
"Apis.Details.Policies.CreatePolicy.create.new.policy": "Create New Policy",
"Apis.Details.Policies.CreatePolicy.create.new.policy.link": "Want to create a common policy that will be visible to all APIs instead?",
"Apis.Details.Policies.DeletePolicy.cancel": "Cancel",
Expand Down Expand Up @@ -2045,6 +2047,7 @@
"UnexpectedError.logout": "Logout",
"UnexpectedError.message": "Error occurred due to invalid request",
"UnexpectedError.title": "Internal Server Error",
"Uploading.Policies.Error": "Incompatible file type",
"Workflow.ApplicationCreation.updateStatus.has.errors": "Unable to complete subscription creation approve/reject process.",
"Workflow.SubscriptionCreation.List.empty.content.subscriptioncreations": "There are no pending workflow requests for subscription creation.",
"Workflow.SubscriptionCreation.List.empty.title.subscriptioncreations": "Subscription Creation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ interface AttachedPolicyCardProps {
target: string;
allPolicies: PolicySpec[] | null;
isAPILevelPolicy: boolean;
listOriginatedFromCommonPolicies: string[];
isApiRevision: boolean;
}

/**
Expand All @@ -61,6 +63,8 @@ const AttachedPolicyCard: FC<AttachedPolicyCardProps> = ({
target,
allPolicies,
isAPILevelPolicy,
listOriginatedFromCommonPolicies,
isApiRevision
}) => {
const { api } = useContext<any>(ApiContext);
const { deleteApiOperation } = useContext<any>(ApiOperationContext);
Expand Down Expand Up @@ -155,6 +159,8 @@ const AttachedPolicyCard: FC<AttachedPolicyCardProps> = ({
handleDelete={handleDelete}
setDrawerOpen={setDrawerOpen}
PolicyConfigurationEditDrawer={PolicyConfigurationEditDrawer}
listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies}
isApiRevision={isApiRevision}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ interface AttachedPolicyListProps {
verb: string;
allPolicies: PolicySpec[] | null;
isAPILevelPolicy: boolean;
listOriginatedFromCommonPolicies: string[];
isApiRevision: boolean;
}

/**
Expand All @@ -54,6 +56,8 @@ const AttachedPolicyList: FC<AttachedPolicyListProps> = ({
verb,
allPolicies,
isAPILevelPolicy,
listOriginatedFromCommonPolicies,
isApiRevision
}) => {
const reversedPolicyList = [...currentPolicyList].reverse();
const policyListToDisplay =
Expand Down Expand Up @@ -105,6 +109,8 @@ const AttachedPolicyList: FC<AttachedPolicyListProps> = ({
handleDragEnd={handleDragEnd}
policyListToDisplay={policyListToDisplay}
AttachedPolicyCard={AttachedPolicyCard}
listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies}
isApiRevision={isApiRevision}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ const Policies: React.FC = () => {

const [api, updateAPI] = useAPI();
const [updating, setUpdating] = useState(false);
const [policies, setPolicies] = useState<Policy[] | null>(null);
const [apiPolicies, setApiPolicies] = useState<Policy[] | null>(null);
const [commonPolicies, setCommonPolicies] = useState<Policy[] | null>(null);
const [policies, setPolicies] = useState<Policy[]>([]);
const [allPolicies, setAllPolicies] = useState<PolicySpec[] | null>(null);
const [expandedResource, setExpandedResource] = useState<string | null>(null);
const [isChoreoConnectEnabled, setIsChoreoConnectEnabled] = useState(api.gatewayType === 'wso2/apk');
Expand Down Expand Up @@ -175,53 +177,59 @@ const Policies: React.FC = () => {
const commonPoliciesPromise = API.getCommonOperationPolicies();
Promise.all([apiPoliciesPromise, commonPoliciesPromise]).then((response) => {
const [apiPoliciesResponse, commonPoliciesResponse] = response;
const apiSpecificPolicies = apiPoliciesResponse.body.list;
const commonPolicies = commonPoliciesResponse.body.list;
const mergedList = [...commonPolicies, ...apiSpecificPolicies];
const apiSpecificPoliciesList = apiPoliciesResponse.body.list;
const commonPoliciesList = commonPoliciesResponse.body.list;
const mergedList = [...commonPoliciesList, ...apiSpecificPoliciesList];

// Get all common policies and API specific policies
setAllPolicies(mergedList);

let unionByPolicyDisplayName;
if (showMultiVersionPolicies) {
// Get the union of policies depending on the policy display name and version
unionByPolicyDisplayName = [...mergedList
.reduce((map, obj) => map.set(obj.name + obj.version, obj), new Map()).values()];
} else {
// Get the union of policies depending on the policy display name
unionByPolicyDisplayName = [...mergedList
.reduce((map, obj) => map.set(obj.name, obj), new Map()).values()];
}
unionByPolicyDisplayName.sort(
let apiPolicyByPolicyDisplayName;
let commonPolicyByPolicyDisplayName;
// Get the union of policies depending on the policy display name and version
apiPolicyByPolicyDisplayName = [...apiSpecificPoliciesList
.reduce((map: Map<string, Policy>, obj: Policy) =>
map.set((showMultiVersionPolicies ? obj.name + obj.version : obj.name), obj),
new Map()).values()];

commonPolicyByPolicyDisplayName = [...commonPoliciesList
.reduce((map: Map<string, Policy>, obj: Policy) =>
map.set((showMultiVersionPolicies ? obj.name + obj.version : obj.name), obj),
new Map()).values()];

apiPolicyByPolicyDisplayName.sort(
(a: Policy, b: Policy) => a.name.localeCompare(b.name))

let filteredByGatewayTypeList = null;
if (!isChoreoConnectEnabled) {
// Get synpase gateway supported policies
filteredByGatewayTypeList = unionByPolicyDisplayName.filter(
(policy: Policy) => policy.supportedGateways.includes('Synapse'));
} else {
// Get CC gateway supported policies
filteredByGatewayTypeList = unionByPolicyDisplayName.filter(
(policy: Policy) => policy.supportedGateways.includes('ChoreoConnect'));
}
commonPolicyByPolicyDisplayName.sort(
(a: Policy, b: Policy) => a.name.localeCompare(b.name))

let filteredByAPITypeList = null;
if (api.type === "HTTP") {
let filteredApiPolicyByGatewayTypeList = null;
let filteredCommonPolicyByGatewayTypeList = null;

let gatewayType = isChoreoConnectEnabled ? 'ChoreoConnect' : 'Synapse';
// Get relevant gateway supported policies
filteredApiPolicyByGatewayTypeList = apiPolicyByPolicyDisplayName.filter(
(policy: Policy) => policy.supportedGateways.includes(gatewayType));
filteredCommonPolicyByGatewayTypeList = commonPolicyByPolicyDisplayName.filter(
(policy: Policy) => policy.supportedGateways.includes(gatewayType));

let filteredApiPoliciesByAPITypeList = [];
let filteredCommonPoliciesByAPITypeList = [];

if (api.type === "HTTP" || api.type === "SOAP" || api.type === "SOAPTOREST") {
// Get HTTP supported policies
filteredByAPITypeList = filteredByGatewayTypeList.filter(
(policy: Policy) => policy.supportedApiTypes.includes('HTTP'));
} else if (api.type === "SOAP"){
// Get SOAP supported policies
filteredByAPITypeList = filteredByGatewayTypeList.filter(
(policy: Policy) => policy.supportedApiTypes.includes('SOAP'));
} else if (api.type === "SOAPTOREST"){
// Get SOAP to REST supported policies
filteredByAPITypeList = filteredByGatewayTypeList.filter(
(policy: Policy) => policy.supportedApiTypes.includes('SOAPTOREST'));
filteredApiPoliciesByAPITypeList = filteredApiPolicyByGatewayTypeList.filter(
(policy: Policy) => policy.supportedApiTypes.includes(api.type));
filteredCommonPoliciesByAPITypeList = filteredCommonPolicyByGatewayTypeList.filter(
(policy: Policy) => policy.supportedApiTypes.includes(api.type));
}

setPolicies(filteredByAPITypeList);
setApiPolicies(filteredApiPoliciesByAPITypeList);
setCommonPolicies(filteredCommonPoliciesByAPITypeList);
const combinedPolicyList = [...filteredCommonPoliciesByAPITypeList, ...filteredApiPoliciesByAPITypeList];
combinedPolicyList.sort(
(a: Policy, b: Policy) => a.name.localeCompare(b.name))
setPolicies(combinedPolicyList);

}).catch((error) => {
console.error(error);
Expand Down Expand Up @@ -498,7 +506,7 @@ const Policies: React.FC = () => {
],
);

if (!policies || !openAPISpec || updating) {
if (!apiPolicies || !commonPolicies || !openAPISpec || updating) {
return <Progress per={90} message='Loading Policies ...' />
}

Expand Down Expand Up @@ -597,7 +605,8 @@ const Policies: React.FC = () => {
</Box>
<Box width='35%' p={1}>
<PolicyList
policyList={policies}
apiPolicyList={apiPolicies}
commonPolicyList={commonPolicies}
fetchPolicies={fetchPolicies}
isChoreoConnectEnabled={isChoreoConnectEnabled}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
const { apiOperations } = useContext<any>(ApiOperationContext);
const { apiLevelPolicies } = useContext<any>(ApiOperationContext);
const { api } = useContext<any>(APIContext);
const [listOriginatedFromCommonPolicies, setListOriginatedFromCommonPolicies] = useState<string[]>([]);

useEffect(() => {
const requestList = [];
Expand Down Expand Up @@ -119,12 +120,13 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
op.verb.toLowerCase() === verb.toLowerCase(),
) : null;
const apiPolicies = (isAPILevelPolicy) ? apiLevelPolicies : null;
const originatedFromCommonPolicies : string[] = [];

// Populate request flow attached policy list
const requestFlowList: AttachedPolicy[] = [];
const requestFlow = (isAPILevelPolicy) ? apiPolicies.request : operationInAction.operationPolicies.request;
for (const requestFlowAttachedPolicy of requestFlow) {
const { policyId, policyName, policyVersion, uuid } =
const { policyId, policyName, uuid } =
requestFlowAttachedPolicy;
if (policyId === null) {
// Handling migration flow
Expand All @@ -136,14 +138,11 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
uniqueKey: uuid,
});
} else {
const policyObj = allPolicies?.find(
(policy: PolicySpec) =>
policy.name === policyName &&
policy.version === policyVersion,
);
const policyObj = allPolicies?.find((policy: PolicySpec) => policy.id === policyId);
if (policyObj) {
requestFlowList.push({ ...policyObj, uniqueKey: uuid });
} else {
originatedFromCommonPolicies.push(policyId);
try {
// eslint-disable-next-line no-await-in-loop
const policyResponse = await API.getOperationPolicy(
Expand All @@ -167,7 +166,7 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
const responseFlowList: AttachedPolicy[] = [];
const responseFlow = isAPILevelPolicy ? apiPolicies.response : operationInAction.operationPolicies.response;
for (const responseFlowAttachedPolicy of responseFlow) {
const { policyId, policyName, policyVersion, uuid } =
const { policyId, policyName, uuid } =
responseFlowAttachedPolicy;
if (policyId === null) {
// Handling migration flow
Expand All @@ -179,14 +178,11 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
uniqueKey: uuid,
});
} else {
const policyObj = allPolicies?.find(
(policy: PolicySpec) =>
policy.name === policyName &&
policy.version === policyVersion,
);
const policyObj = allPolicies?.find((policy: PolicySpec) => policy.id === policyId);
if (policyObj) {
responseFlowList.push({ ...policyObj, uniqueKey: uuid });
} else {
originatedFromCommonPolicies.push(policyId);
try {
// eslint-disable-next-line no-await-in-loop
const policyResponse = await API.getOperationPolicy(
Expand All @@ -211,7 +207,7 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
const faultFlowList: AttachedPolicy[] = [];
const faultFlow = isAPILevelPolicy ? apiPolicies.fault : operationInAction.operationPolicies.fault;
for (const faultFlowAttachedPolicy of faultFlow) {
const { policyId, policyName, policyVersion, uuid } =
const { policyId, policyName, uuid } =
faultFlowAttachedPolicy;
if (policyId === null) {
// Handling migration flow
Expand All @@ -223,14 +219,11 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
uniqueKey: uuid,
});
} else {
const policyObj = allPolicies?.find(
(policy: PolicySpec) =>
policy.name === policyName &&
policy.version === policyVersion,
);
const policyObj = allPolicies?.find((policy: PolicySpec) => policy.id === policyId);
if (policyObj) {
faultFlowList.push({ ...policyObj, uniqueKey: uuid });
} else {
originatedFromCommonPolicies.push(policyId);
try {
// eslint-disable-next-line no-await-in-loop
const policyResponse = await API.getOperationPolicy(
Expand All @@ -250,6 +243,7 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
}
setFaultFlowPolicyList(faultFlowList);
}
setListOriginatedFromCommonPolicies(originatedFromCommonPolicies);
})();
}, [apiOperations, apiLevelPolicies]);

Expand All @@ -271,6 +265,8 @@ const PoliciesExpansion: FC<PoliciesExpansionProps> = ({
faultFlowDroppablePolicyList={faultFlowDroppablePolicyList}
FlowArrow={FlowArrow}
PolicyDropzone={PolicyDropzone}
listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies}
isApiRevision={api.isRevision}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ interface PolicyDropzoneProps {
verb: string;
allPolicies: PolicySpec[] | null;
isAPILevelPolicy: boolean;
listOriginatedFromCommonPolicies: string[];
isApiRevision: boolean;
}

/**
Expand All @@ -106,6 +108,8 @@ const PolicyDropzone: FC<PolicyDropzoneProps> = ({
verb,
allPolicies,
isAPILevelPolicy,
listOriginatedFromCommonPolicies,
isApiRevision
}) => {

const [droppedPolicy, setDroppedPolicy] = useState<Policy | null>(null);
Expand Down Expand Up @@ -134,6 +138,8 @@ const PolicyDropzone: FC<PolicyDropzoneProps> = ({
setDroppedPolicy={setDroppedPolicy}
AttachedPolicyList={AttachedPolicyList}
PolicyConfiguringDrawer={PolicyConfiguringDrawer}
listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies}
isApiRevision={isApiRevision}
/>
);
};
Expand Down
Loading

0 comments on commit a069d97

Please sign in to comment.