From a069d97d7398ad8f843a4ec7f349706d80a0f0eb Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Tue, 28 Jan 2025 01:47:50 +0530 Subject: [PATCH] UI implementation for allowing to have api policy and a common policy with same name and same version. UI fix for https://github.com/wso2/api-manager/issues/3109 --- .../main/webapp/site/public/locales/en.json | 5 +- .../Details/Policies/AttachedPolicyCard.tsx | 6 + .../Details/Policies/AttachedPolicyList.tsx | 6 + .../Apis/Details/Policies/Policies.tsx | 89 ++++---- .../Details/Policies/PoliciesExpansion.tsx | 32 ++- .../Apis/Details/Policies/PolicyDropzone.tsx | 6 + .../Apis/Details/Policies/PolicyList.tsx | 46 +++- .../Details/Policies/components/TabPanel.tsx | 9 +- .../Shared/PoliciesUI/AttachedPolicyCard.tsx | 216 +++++++++++++----- .../Shared/PoliciesUI/AttachedPolicyList.tsx | 6 + .../Shared/PoliciesUI/PoliciesExpansion.tsx | 12 +- .../Shared/PoliciesUI/PolicyDropzone.tsx | 8 +- .../components/Shared/PoliciesUI/TabPanel.tsx | 123 ++++++++-- 13 files changed, 418 insertions(+), 146 deletions(-) diff --git a/portals/publisher/src/main/webapp/site/public/locales/en.json b/portals/publisher/src/main/webapp/site/public/locales/en.json index cd36b58f3d3..c26cc8fae93 100644 --- a/portals/publisher/src/main/webapp/site/public/locales/en.json +++ b/portals/publisher/src/main/webapp/site/public/locales/en.json @@ -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", @@ -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", @@ -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", diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyCard.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyCard.tsx index 6f383a69bc8..8336f2bcb38 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyCard.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyCard.tsx @@ -45,6 +45,8 @@ interface AttachedPolicyCardProps { target: string; allPolicies: PolicySpec[] | null; isAPILevelPolicy: boolean; + listOriginatedFromCommonPolicies: string[]; + isApiRevision: boolean; } /** @@ -61,6 +63,8 @@ const AttachedPolicyCard: FC = ({ target, allPolicies, isAPILevelPolicy, + listOriginatedFromCommonPolicies, + isApiRevision }) => { const { api } = useContext(ApiContext); const { deleteApiOperation } = useContext(ApiOperationContext); @@ -155,6 +159,8 @@ const AttachedPolicyCard: FC = ({ handleDelete={handleDelete} setDrawerOpen={setDrawerOpen} PolicyConfigurationEditDrawer={PolicyConfigurationEditDrawer} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> ); }; diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyList.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyList.tsx index bbd37b06e28..6da49a8725c 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyList.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/AttachedPolicyList.tsx @@ -38,6 +38,8 @@ interface AttachedPolicyListProps { verb: string; allPolicies: PolicySpec[] | null; isAPILevelPolicy: boolean; + listOriginatedFromCommonPolicies: string[]; + isApiRevision: boolean; } /** @@ -54,6 +56,8 @@ const AttachedPolicyList: FC = ({ verb, allPolicies, isAPILevelPolicy, + listOriginatedFromCommonPolicies, + isApiRevision }) => { const reversedPolicyList = [...currentPolicyList].reverse(); const policyListToDisplay = @@ -105,6 +109,8 @@ const AttachedPolicyList: FC = ({ handleDragEnd={handleDragEnd} policyListToDisplay={policyListToDisplay} AttachedPolicyCard={AttachedPolicyCard} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> ); }; diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/Policies.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/Policies.tsx index 36df4331cd0..63711c3d11b 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/Policies.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/Policies.tsx @@ -91,7 +91,9 @@ const Policies: React.FC = () => { const [api, updateAPI] = useAPI(); const [updating, setUpdating] = useState(false); - const [policies, setPolicies] = useState(null); + const [apiPolicies, setApiPolicies] = useState(null); + const [commonPolicies, setCommonPolicies] = useState(null); + const [policies, setPolicies] = useState([]); const [allPolicies, setAllPolicies] = useState(null); const [expandedResource, setExpandedResource] = useState(null); const [isChoreoConnectEnabled, setIsChoreoConnectEnabled] = useState(api.gatewayType === 'wso2/apk'); @@ -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, obj: Policy) => + map.set((showMultiVersionPolicies ? obj.name + obj.version : obj.name), obj), + new Map()).values()]; + + commonPolicyByPolicyDisplayName = [...commonPoliciesList + .reduce((map: Map, 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); @@ -498,7 +506,7 @@ const Policies: React.FC = () => { ], ); - if (!policies || !openAPISpec || updating) { + if (!apiPolicies || !commonPolicies || !openAPISpec || updating) { return } @@ -597,7 +605,8 @@ const Policies: React.FC = () => { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesExpansion.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesExpansion.tsx index 410911f7d91..c3d63da478d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesExpansion.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PoliciesExpansion.tsx @@ -89,6 +89,7 @@ const PoliciesExpansion: FC = ({ const { apiOperations } = useContext(ApiOperationContext); const { apiLevelPolicies } = useContext(ApiOperationContext); const { api } = useContext(APIContext); + const [listOriginatedFromCommonPolicies, setListOriginatedFromCommonPolicies] = useState([]); useEffect(() => { const requestList = []; @@ -119,12 +120,13 @@ const PoliciesExpansion: FC = ({ 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 @@ -136,14 +138,11 @@ const PoliciesExpansion: FC = ({ 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( @@ -167,7 +166,7 @@ const PoliciesExpansion: FC = ({ 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 @@ -179,14 +178,11 @@ const PoliciesExpansion: FC = ({ 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( @@ -211,7 +207,7 @@ const PoliciesExpansion: FC = ({ 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 @@ -223,14 +219,11 @@ const PoliciesExpansion: FC = ({ 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( @@ -250,6 +243,7 @@ const PoliciesExpansion: FC = ({ } setFaultFlowPolicyList(faultFlowList); } + setListOriginatedFromCommonPolicies(originatedFromCommonPolicies); })(); }, [apiOperations, apiLevelPolicies]); @@ -271,6 +265,8 @@ const PoliciesExpansion: FC = ({ faultFlowDroppablePolicyList={faultFlowDroppablePolicyList} FlowArrow={FlowArrow} PolicyDropzone={PolicyDropzone} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={api.isRevision} /> ); }; diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyDropzone.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyDropzone.tsx index 8e9292dc0e5..6acd54f73f0 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyDropzone.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyDropzone.tsx @@ -89,6 +89,8 @@ interface PolicyDropzoneProps { verb: string; allPolicies: PolicySpec[] | null; isAPILevelPolicy: boolean; + listOriginatedFromCommonPolicies: string[]; + isApiRevision: boolean; } /** @@ -106,6 +108,8 @@ const PolicyDropzone: FC = ({ verb, allPolicies, isAPILevelPolicy, + listOriginatedFromCommonPolicies, + isApiRevision }) => { const [droppedPolicy, setDroppedPolicy] = useState(null); @@ -134,6 +138,8 @@ const PolicyDropzone: FC = ({ setDroppedPolicy={setDroppedPolicy} AttachedPolicyList={AttachedPolicyList} PolicyConfiguringDrawer={PolicyConfiguringDrawer} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> ); }; diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyList.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyList.tsx index 49238d88f69..6a79999aa6d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyList.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/PolicyList.tsx @@ -68,7 +68,8 @@ const StyledPaper = styled(Paper)(({ theme }: { theme: Theme }) => ({ })); interface PolicyListPorps { - policyList: Policy[]; + apiPolicyList: Policy[]; + commonPolicyList: Policy[]; fetchPolicies: () => void; isChoreoConnectEnabled: boolean; } @@ -78,7 +79,7 @@ interface PolicyListPorps { * @param {JSON} props Input props from parent components. * @returns {TSX} List of policies local to the API segment. */ -const PolicyList: FC = ({policyList, fetchPolicies, isChoreoConnectEnabled}) => { +const PolicyList: FC = ({apiPolicyList, commonPolicyList, fetchPolicies, isChoreoConnectEnabled}) => { const [selectedTab, setSelectedTab] = useState(0); // Request flow related tab is active by default const [dialogOpen, setDialogOpen] = React.useState(false); @@ -176,7 +177,16 @@ const PolicyList: FC = ({policyList, fetchPolicies, isChoreoCon + policy.applicableFlows.includes( + 'request', + ) && + policy.supportedGateways.includes( + gatewayType, + ), + )} + apiPolicyList={apiPolicyList.filter( (policy) => policy.applicableFlows.includes( 'request', @@ -190,7 +200,16 @@ const PolicyList: FC = ({policyList, fetchPolicies, isChoreoCon fetchPolicies={fetchPolicies} /> + policy.applicableFlows.includes( + 'response', + ) && + policy.supportedGateways.includes( + gatewayType, + ), + )} + apiPolicyList={apiPolicyList.filter( (policy) => policy.applicableFlows.includes( 'response', @@ -205,9 +224,24 @@ const PolicyList: FC = ({policyList, fetchPolicies, isChoreoCon /> {!isChoreoConnectEnabled && ( - policy.applicableFlows.includes('fault'), + commonPolicyList={commonPolicyList.filter( + (policy) => + policy.applicableFlows.includes( + 'fault', + ) && + policy.supportedGateways.includes( + gatewayType, + ), )} + apiPolicyList={apiPolicyList.filter( + (policy) => + policy.applicableFlows.includes( + 'fault', + ) && + policy.supportedGateways.includes( + gatewayType, + ), + )} index={2} selectedTab={selectedTab} fetchPolicies={fetchPolicies} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/components/TabPanel.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/components/TabPanel.tsx index b4aae4a707b..fae743e7748 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/components/TabPanel.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Policies/components/TabPanel.tsx @@ -25,7 +25,8 @@ import type { Policy } from '../Types'; interface TabPanelProps { children?: React.ReactNode; index: number; - policyList: Policy[]; + commonPolicyList: Policy[]; + apiPolicyList: Policy[]; selectedTab: number; fetchPolicies: () => void; } @@ -38,7 +39,8 @@ interface TabPanelProps { */ const TabPanel: FC = ({ index, - policyList, + commonPolicyList, + apiPolicyList, selectedTab, fetchPolicies, }) => { @@ -50,7 +52,8 @@ const TabPanel: FC = ({ selectedTab={selectedTab} index={index} currentFlow={currentFlow} - policyList={policyList} + commonPolicyList={commonPolicyList} + apiPolicyList={apiPolicyList} fetchPolicies={fetchPolicies} DraggablePolicyCard={DraggablePolicyCard} /> diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyCard.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyCard.tsx index 8927c228016..2691d0f6bf7 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyCard.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyCard.tsx @@ -24,6 +24,7 @@ import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; +import Typography from '@mui/material/Typography'; import DeleteIcon from '@mui/icons-material/Delete'; import CloudDownloadIcon from '@mui/icons-material/CloudDownload'; import Utils from 'AppData/Utils'; @@ -35,6 +36,9 @@ const classes = { actionsBox: `${PREFIX}-actionsBox` }; +const COMMON_POLICY = "Common Policy"; +const API_POLICY = "API Policy"; + // TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. const Root = styled('div')(() => ({ [`& .${classes.actionsBox}`]: { @@ -52,6 +56,8 @@ interface AttachedPolicyCardSharedProps { allPolicies: PolicySpec[] | null; isAPILevelPolicy: boolean; drawerOpen: any; + listOriginatedFromCommonPolicies?: string[]; + isApiRevision?: boolean; handleDrawerOpen: () => void; handlePolicyDownload: (event: React.MouseEvent) => void; handleDelete: (event: React.MouseEvent) => void; @@ -72,6 +78,8 @@ const AttachedPolicyCardShared: FC = ({ allPolicies, isAPILevelPolicy, drawerOpen, + listOriginatedFromCommonPolicies, + isApiRevision, handleDrawerOpen, handlePolicyDownload, handleDelete, @@ -106,70 +114,154 @@ const AttachedPolicyCardShared: FC = ({ backgroundColor: policyBackgroundColor, opacity: isDragging ? 0.5 : 1, }; - return ( - ( -
- +
- - {Utils.stringAvatar( - policyObj.displayName.toUpperCase(), - )} - - - - - - - + {`*${policyType}\n${policyObj.displayName} : ${policyObj.version}`} + + } + placement='top' + > + + {Utils.stringAvatar( + policyObj.displayName.toUpperCase(), + )} + + + + + + + + + + +
+ {drawerOpen && ( + + )} + + + ); + } else { + return ( + ( +
+ - - - -
- {drawerOpen && ( - - )} -
) - ); + + {Utils.stringAvatar( + policyObj.displayName.toUpperCase(), + )} + +
+ + + + + + + + +
+ {drawerOpen && ( + + )} +
) + ); + } } export default AttachedPolicyCardShared; diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyList.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyList.tsx index 2f651fcb5c6..8f793aa1ec4 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyList.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/AttachedPolicyList.tsx @@ -40,6 +40,8 @@ interface AttachedPolicyListSharedProps { handleDragEnd: (event: DragEndEvent) => void; policyListToDisplay: AttachedPolicy[]; AttachedPolicyCard: any; + listOriginatedFromCommonPolicies?: string[]; + isApiRevision?: boolean; } const AttachedPolicyListShared: FC = ({ @@ -54,6 +56,8 @@ const AttachedPolicyListShared: FC = ({ handleDragEnd, policyListToDisplay, AttachedPolicyCard, + listOriginatedFromCommonPolicies, + isApiRevision }) => { return ( <> @@ -77,6 +81,8 @@ const AttachedPolicyListShared: FC = ({ verb={verb} allPolicies={allPolicies} isAPILevelPolicy={isAPILevelPolicy} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> ))} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PoliciesExpansion.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PoliciesExpansion.tsx index 1bbefed61f7..c903e9b333e 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PoliciesExpansion.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PoliciesExpansion.tsx @@ -56,6 +56,8 @@ interface PoliciesExpansionSharedProps { faultFlowDroppablePolicyList: string[]; FlowArrow: any; PolicyDropzone: any; + listOriginatedFromCommonPolicies?: string[]; + isApiRevision?: boolean; } const PoliciesExpansionShared: FC = ({ @@ -74,7 +76,9 @@ const PoliciesExpansionShared: FC = ({ setFaultFlowPolicyList, faultFlowDroppablePolicyList, FlowArrow, - PolicyDropzone + PolicyDropzone, + listOriginatedFromCommonPolicies, + isApiRevision }) => { @@ -106,6 +110,8 @@ const PoliciesExpansionShared: FC = ({ verb={verb} allPolicies={allPolicies} isAPILevelPolicy={isAPILevelPolicy} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} />
@@ -128,6 +134,8 @@ const PoliciesExpansionShared: FC = ({ verb={verb} allPolicies={allPolicies} isAPILevelPolicy={isAPILevelPolicy} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> {!isChoreoConnectEnabled && ( @@ -151,6 +159,8 @@ const PoliciesExpansionShared: FC = ({ verb={verb} allPolicies={allPolicies} isAPILevelPolicy={isAPILevelPolicy} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} />
)} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PolicyDropzone.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PolicyDropzone.tsx index 863300d7e99..7fe492a355d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PolicyDropzone.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/PolicyDropzone.tsx @@ -91,6 +91,8 @@ interface PolicyDropzoneSharedProps { setDroppedPolicy: any; AttachedPolicyList: any; PolicyConfiguringDrawer: any; + listOriginatedFromCommonPolicies?: string[]; + isApiRevision?: boolean; } const PolicyDropzoneShared: FC = ({ @@ -107,7 +109,9 @@ const PolicyDropzoneShared: FC = ({ droppedPolicy, setDroppedPolicy, AttachedPolicyList, - PolicyConfiguringDrawer + PolicyConfiguringDrawer, + listOriginatedFromCommonPolicies, + isApiRevision }) => { return ( @@ -146,6 +150,8 @@ const PolicyDropzoneShared: FC = ({ verb={verb} allPolicies={allPolicies} isAPILevelPolicy={isAPILevelPolicy} + listOriginatedFromCommonPolicies={listOriginatedFromCommonPolicies} + isApiRevision={isApiRevision} /> )} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/TabPanel.tsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/TabPanel.tsx index bba8939adfc..4bd859de96c 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/TabPanel.tsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/PoliciesUI/TabPanel.tsx @@ -16,18 +16,23 @@ * under the License. */ -import { Box } from '@mui/material'; +import { Box, Accordion, AccordionSummary, AccordionDetails } from '@mui/material'; import React, { FC } from 'react'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import Typography from '@mui/material/Typography'; +import { FormattedMessage } from 'react-intl'; import type { Policy } from './Types'; interface TabPanelSharedProps { children?: React.ReactNode; currentFlow: string; index: number; - policyList: Policy[]; selectedTab: number; fetchPolicies: () => void; DraggablePolicyCard: any; + policyList?: Policy[]; + commonPolicyList?: Policy[]; + apiPolicyList?: Policy[]; } const TabPanelShared: FC = ({ @@ -35,17 +40,20 @@ const TabPanelShared: FC = ({ index, currentFlow, policyList, + commonPolicyList, + apiPolicyList, fetchPolicies, - DraggablePolicyCard + DraggablePolicyCard, }) => { - return ( - + ); + } else { + return ( + + ); + } } export default TabPanelShared; \ No newline at end of file