diff --git a/portals/admin/src/main/webapp/source/src/app/components/Base/RouteMenuMapping.jsx b/portals/admin/src/main/webapp/source/src/app/components/Base/RouteMenuMapping.jsx index 3ebcbde55e9..90eed0ea95d 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Base/RouteMenuMapping.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Base/RouteMenuMapping.jsx @@ -40,7 +40,6 @@ import ListRoles from 'AppComponents//RolePermissions/ListRoles.jsx'; import TenantConfSave from 'AppComponents/AdvancedSettings/TenantConfSave'; import Policies from 'AppComponents/Governance/Policies'; import RulesetCatalog from 'AppComponents/Governance/RulesetCatalog'; -import Overview from 'AppComponents/Governance/Overview'; import BusinessIcon from '@mui/icons-material/Business'; import Organizations from 'AppComponents/Organizations/ListOrganizations'; @@ -70,6 +69,7 @@ import AccountTreeIcon from '@mui/icons-material/AccountTree'; import ListApis from '../APISettings/ListApis'; import UsageReport from '../APISettings/UsageReport'; import ListLabels from '../Labels/ListLabels'; +import ComplianceDashboard from '../Governance/ComplianceDashboard'; const RouteMenuMapping = (intl) => [ { @@ -318,13 +318,13 @@ const RouteMenuMapping = (intl) => [ }), children: [ { - id: 'Overview', + id: 'Compliance', displayText: intl.formatMessage({ - id: 'Base.RouteMenuMapping.overview', - defaultMessage: 'Overview', + id: 'Base.RouteMenuMapping.compliance', + defaultMessage: 'Compliance', }), - path: '/governance/overview', - component: Overview, + path: '/governance/compliance', + component: ComplianceDashboard, icon: , }, { diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/Compliance.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/Compliance.jsx similarity index 89% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/Compliance.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/Compliance.jsx index c82c90b1cab..094be9ec7d5 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/Compliance.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/Compliance.jsx @@ -95,7 +95,7 @@ export default function Compliance(props) { width='full' title={( @@ -104,15 +104,15 @@ export default function Compliance(props) { > @@ -140,7 +140,7 @@ export default function Compliance(props) { sx={{ fontWeight: 'medium' }} > @@ -150,7 +150,7 @@ export default function Compliance(props) { align='center' > @@ -164,7 +164,7 @@ export default function Compliance(props) { width='full' title={( @@ -179,20 +179,20 @@ export default function Compliance(props) { }} > @@ -225,7 +225,7 @@ export default function Compliance(props) { sx={{ fontWeight: 'bold', mb: 2 }} > @@ -243,18 +243,18 @@ export default function Compliance(props) { sx={{ fontWeight: 'bold', mb: 2 }} > diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/PolicyAdherenceSummaryTable.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/PolicyAdherenceSummaryTable.jsx similarity index 92% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/PolicyAdherenceSummaryTable.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/PolicyAdherenceSummaryTable.jsx index dd5af4eb493..772264c5957 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/PolicyAdherenceSummaryTable.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/PolicyAdherenceSummaryTable.jsx @@ -55,7 +55,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { return ( {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.pending', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.pending', defaultMessage: 'N/A - Waiting for policy evaluation', })} @@ -66,7 +66,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { return ( {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.not.applied', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.not.applied', defaultMessage: 'N/A - Policy not applied', })} @@ -81,7 +81,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.followed.count', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.followed.count', defaultMessage: '{followed}/{total} Followed', }, { followed, total })} @@ -150,7 +150,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { { name: 'name', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.column.policy', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.column.policy', defaultMessage: 'Policy', }), options: { @@ -176,7 +176,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { { name: 'status', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.column.status', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.column.status', defaultMessage: 'Status', }), options: { @@ -218,7 +218,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { { name: 'rulesetsList', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.column.rulesets', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.column.rulesets', defaultMessage: 'Rulesets', }), options: { @@ -266,7 +266,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { sx={{ fontWeight: 'medium' }} > {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.empty.title', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.empty.title', defaultMessage: 'No Policies Applied', })} @@ -276,7 +276,7 @@ export default function PolicyAdherenceSummaryTable({ artifactId }) { align='center' > {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.PolicyAdherence.empty.helper', + id: 'Governance.ComplianceDashboard.APICompliance.PolicyAdherence.empty.helper', defaultMessage: 'No governance policies have been applied to this API.', })} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RuleViolationSummary.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RuleViolationSummary.jsx similarity index 94% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RuleViolationSummary.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RuleViolationSummary.jsx index 2d2091e2bda..844297c7061 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RuleViolationSummary.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RuleViolationSummary.jsx @@ -197,7 +197,7 @@ export default function RuleViolationSummary({ artifactId }) { { name: 'name', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.column.rule', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.column.rule', defaultMessage: 'Rule', }), options: { @@ -209,7 +209,7 @@ export default function RuleViolationSummary({ artifactId }) { { name: 'violatedPath', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.column.path', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.column.path', defaultMessage: 'Path', }), options: { @@ -222,7 +222,7 @@ export default function RuleViolationSummary({ artifactId }) { { name: 'message', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.column.message', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.column.message', defaultMessage: 'Message', }), options: { @@ -239,7 +239,7 @@ export default function RuleViolationSummary({ artifactId }) { { name: 'name', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.column.rule', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.column.rule', defaultMessage: 'Rule', }), options: { @@ -251,7 +251,7 @@ export default function RuleViolationSummary({ artifactId }) { { name: 'description', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.column.description', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.column.description', defaultMessage: 'Description', }), options: { @@ -407,22 +407,22 @@ export default function RuleViolationSummary({ artifactId }) { switch (tabIndex) { case 0: return intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.empty.errors', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.empty.errors', defaultMessage: 'No Error violations found', }); case 1: return intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.empty.warnings', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.empty.warnings', defaultMessage: 'No Warning violations found', }); case 2: return intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.empty.info', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.empty.info', defaultMessage: 'No Info violations found', }); case 3: return intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.empty.passed', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.empty.passed', defaultMessage: 'No Passed rules found', }); default: @@ -485,7 +485,7 @@ export default function RuleViolationSummary({ artifactId }) { icon={} iconPosition='start' label={intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.tab.errors', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.tab.errors', defaultMessage: 'Errors ({count})', }, { count: getTotalRuleCount(complianceData.errors) })} /> @@ -493,7 +493,7 @@ export default function RuleViolationSummary({ artifactId }) { icon={} iconPosition='start' label={intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.tab.warnings', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.tab.warnings', defaultMessage: 'Warnings ({count})', }, { count: getTotalRuleCount(complianceData.warnings) })} /> @@ -501,7 +501,7 @@ export default function RuleViolationSummary({ artifactId }) { icon={} iconPosition='start' label={intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.tab.info', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.tab.info', defaultMessage: 'Info ({count})', }, { count: getTotalRuleCount(complianceData.info) })} /> @@ -509,7 +509,7 @@ export default function RuleViolationSummary({ artifactId }) { icon={} iconPosition='start' label={intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RuleViolation.tab.passed', + id: 'Governance.ComplianceDashboard.APICompliance.RuleViolation.tab.passed', defaultMessage: 'Passed ({count})', }, { count: getTotalRuleCount(complianceData.passed) })} /> diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RulesetAdherenceSummaryTable.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RulesetAdherenceSummaryTable.jsx similarity index 93% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RulesetAdherenceSummaryTable.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RulesetAdherenceSummaryTable.jsx index 45305af21e3..ce9e2c8ebf2 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/APICompliance/RulesetAdherenceSummaryTable.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/APICompliance/RulesetAdherenceSummaryTable.jsx @@ -61,7 +61,7 @@ export default function RulesetAdherenceSummaryTable({ artifactId }) { {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RulesetAdherence.empty.title', + id: 'Governance.ComplianceDashboard.APICompliance.RulesetAdherence.empty.title', defaultMessage: 'No Rulesets Found', })} @@ -237,7 +237,7 @@ export default function RulesetAdherenceSummaryTable({ artifactId }) { align='center' > {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.RulesetAdherence.empty.helper', + id: 'Governance.ComplianceDashboard.APICompliance.RulesetAdherence.empty.helper', defaultMessage: 'No governance rulesets have been applied for this API.', })} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/ApiComplianceTable.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/ApiComplianceTable.jsx similarity index 92% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/ApiComplianceTable.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/ApiComplianceTable.jsx index ff09459ea30..79377a33aee 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/ApiComplianceTable.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/ApiComplianceTable.jsx @@ -55,7 +55,7 @@ export default function ApiComplianceTable() { return ( {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.pending', + id: 'Governance.ComplianceDashboard.APICompliance.pending', defaultMessage: 'N/A - Waiting for policy evaluation', })} @@ -66,7 +66,7 @@ export default function ApiComplianceTable() { return ( {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.no.policies', + id: 'Governance.ComplianceDashboard.APICompliance.no.policies', defaultMessage: 'N/A - No policies to evaluate', })} @@ -81,7 +81,7 @@ export default function ApiComplianceTable() { {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.followed.count', + id: 'Governance.ComplianceDashboard.APICompliance.followed.count', defaultMessage: '{followed}/{total} Followed', }, { followed, total })} @@ -157,13 +157,13 @@ export default function ApiComplianceTable() { { name: 'name', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.column.api', + id: 'Governance.ComplianceDashboard.APICompliance.column.api', defaultMessage: 'API', }), options: { customBodyRender: (value, tableMeta) => ( - + {tableMeta.rowData[1].name} @@ -187,7 +187,7 @@ export default function ApiComplianceTable() { { name: 'status', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.column.status', + id: 'Governance.ComplianceDashboard.APICompliance.column.status', defaultMessage: 'Status', }), options: { @@ -227,7 +227,7 @@ export default function ApiComplianceTable() { { name: 'policies', label: intl.formatMessage({ - id: 'Governance.Overview.APICompliance.column.policies', + id: 'Governance.ComplianceDashboard.APICompliance.column.policies', defaultMessage: 'Policies', }), options: { @@ -298,7 +298,7 @@ export default function ApiComplianceTable() { sx={{ fontWeight: 'medium' }} > {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.empty.content', + id: 'Governance.ComplianceDashboard.APICompliance.empty.content', defaultMessage: 'No APIs Available', })} @@ -308,7 +308,7 @@ export default function ApiComplianceTable() { align="center" > {intl.formatMessage({ - id: 'Governance.Overview.APICompliance.empty.helper', + id: 'Governance.ComplianceDashboard.APICompliance.empty.helper', defaultMessage: 'Create APIs to start evaluating their compliance.', })} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/PolicyAdherenceTable.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/PolicyAdherenceTable.jsx similarity index 90% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/PolicyAdherenceTable.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/PolicyAdherenceTable.jsx index e7e2ffb7eed..51c4a48024f 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/PolicyAdherenceTable.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/PolicyAdherenceTable.jsx @@ -75,7 +75,7 @@ export default function PolicyAdherenceTable() { return ( {intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.no.apis', + id: 'Governance.ComplianceDashboard.PolicyAdherence.no.apis', defaultMessage: 'N/A - No APIs to evaluate', })} @@ -90,7 +90,7 @@ export default function PolicyAdherenceTable() { {intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.compliant.count', + id: 'Governance.ComplianceDashboard.PolicyAdherence.compliant.count', defaultMessage: '{followed}/{total} Compliant', }, { followed, total })} @@ -120,21 +120,13 @@ export default function PolicyAdherenceTable() { { name: 'name', label: intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.column.policy', + id: 'Governance.ComplianceDashboard.PolicyAdherence.column.policy', defaultMessage: 'Policy', }), options: { customBodyRender: (value, tableMeta) => ( - - {value} - - + {value} ), setCellProps: () => ({ @@ -157,7 +149,7 @@ export default function PolicyAdherenceTable() { { name: 'status', label: intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.column.status', + id: 'Governance.ComplianceDashboard.PolicyAdherence.column.status', defaultMessage: 'Status', }), options: { @@ -195,7 +187,7 @@ export default function PolicyAdherenceTable() { { name: 'progress', label: intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.column.apis', + id: 'Governance.ComplianceDashboard.PolicyAdherence.column.apis', defaultMessage: 'APIs', }), options: { @@ -240,7 +232,7 @@ export default function PolicyAdherenceTable() { } {intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.empty.content', + id: 'Governance.ComplianceDashboard.PolicyAdherence.empty.content', defaultMessage: 'No Governance Policies Available', })} @@ -292,7 +284,7 @@ export default function PolicyAdherenceTable() { align="center" > {intl.formatMessage({ - id: 'Governance.Overview.PolicyAdherence.empty.helper', + id: 'Governance.ComplianceDashboard.PolicyAdherence.empty.helper', defaultMessage: 'Create a new governance policy to start governing the APIs.', })} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/Summary.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/Summary.jsx similarity index 87% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/Summary.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/Summary.jsx index 08bb8df7834..6a4355fa84c 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/Summary.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/Summary.jsx @@ -72,8 +72,8 @@ export default function Summary() { @@ -86,7 +86,7 @@ export default function Summary() { sx={{ fontWeight: 'bold', mb: 2 }} > {intl.formatMessage({ - id: 'Governance.Overview.Summary.policy.adherence', + id: 'Governance.ComplianceDashboard.Summary.policy.adherence', defaultMessage: 'Policy Adherence', })} @@ -96,7 +96,7 @@ export default function Summary() { id: 0, value: policyAdherence.followedPolicies, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.policy.followed', + id: 'Governance.ComplianceDashboard.Summary.policy.followed', defaultMessage: 'Followed ({count})', }, { count: policyAdherence.followedPolicies }) }, @@ -104,7 +104,7 @@ export default function Summary() { id: 1, value: policyAdherence.violatedPolicies, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.policy.violated', + id: 'Governance.ComplianceDashboard.Summary.policy.violated', defaultMessage: 'Violated ({count})', }, { count: policyAdherence.violatedPolicies }) }, @@ -112,7 +112,7 @@ export default function Summary() { id: 2, value: policyAdherence.unAppliedPolicies, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.policy.not.applied', + id: 'Governance.ComplianceDashboard.Summary.policy.not.applied', defaultMessage: 'Not Applied ({count})', }, { count: policyAdherence.unAppliedPolicies }) } @@ -129,7 +129,7 @@ export default function Summary() { sx={{ fontWeight: 'bold', mb: 2 }} > {intl.formatMessage({ - id: 'Governance.Overview.Summary.api.compliance', + id: 'Governance.ComplianceDashboard.Summary.api.compliance', defaultMessage: 'API Compliance', })} @@ -139,7 +139,7 @@ export default function Summary() { id: 0, value: apiCompliance.compliantArtifacts, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.api.compliant', + id: 'Governance.ComplianceDashboard.Summary.api.compliant', defaultMessage: 'Compliant ({count})', }, { count: apiCompliance.compliantArtifacts }) }, @@ -147,7 +147,7 @@ export default function Summary() { id: 1, value: apiCompliance.nonCompliantArtifacts, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.api.non.compliant', + id: 'Governance.ComplianceDashboard.Summary.api.non.compliant', defaultMessage: 'Non-Compliant ({count})', }, { count: apiCompliance.nonCompliantArtifacts }) }, @@ -155,7 +155,7 @@ export default function Summary() { id: 2, value: apiCompliance.pendingArtifacts, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.api.pending', + id: 'Governance.ComplianceDashboard.Summary.api.pending', defaultMessage: 'Pending ({count})', }, { count: apiCompliance.pendingArtifacts }) }, @@ -163,12 +163,12 @@ export default function Summary() { id: 3, value: apiCompliance.notApplicableArtifacts, label: intl.formatMessage({ - id: 'Governance.Overview.Summary.api.not.applicable', + id: 'Governance.ComplianceDashboard.Summary.api.not.applicable', defaultMessage: 'Not Applicable ({count})', }, { count: apiCompliance.notApplicableArtifacts }) } ]} - colors={['#2E96FF', '#FF5252', '#FFC107', 'grey']} + colors={['#00B81D', '#FF5252', '#FFC107', 'grey']} /> @@ -186,7 +186,7 @@ export default function Summary() { sx={{ fontWeight: 'bold', mb: 2 }} > {intl.formatMessage({ - id: 'Governance.Overview.Summary.api.compliance.details', + id: 'Governance.ComplianceDashboard.Summary.api.compliance.details', defaultMessage: 'API Compliance Details', })} @@ -207,7 +207,7 @@ export default function Summary() { sx={{ fontWeight: 'bold', mb: 2 }} > {intl.formatMessage({ - id: 'Governance.Overview.Summary.policy.adherence.details', + id: 'Governance.ComplianceDashboard.Summary.policy.adherence.details', defaultMessage: 'Policy Adherence Details', })} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/index.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/index.jsx similarity index 81% rename from portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/index.jsx rename to portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/index.jsx index 7f5e108e2d4..0199a0f0bae 100755 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Overview/index.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/ComplianceDashboard/index.jsx @@ -27,14 +27,14 @@ import Compliance from './APICompliance/Compliance'; * Render a list * @returns {JSX} Header AppBar components. */ -function Overview() { +function ComplianceDashboard() { return ( - - + + ); } -export default withRouter(Overview); +export default withRouter(ComplianceDashboard); diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ActionConfigDialog.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ActionConfigDialog.jsx index 9ad7bb7dcb9..ddd658b0a71 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ActionConfigDialog.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ActionConfigDialog.jsx @@ -40,7 +40,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import CONSTS from 'AppData/Constants'; export default function ActionConfigDialog({ - open, onClose, onSave, editAction, + open, onClose, onSave, editAction, existingStates = [], }) { const intl = useIntl(); const [formState, setFormState] = useState(editAction || { @@ -95,8 +95,8 @@ export default function ActionConfigDialog({ > @@ -104,7 +104,7 @@ export default function ActionConfigDialog({ @@ -120,15 +120,31 @@ export default function ActionConfigDialog({ })} label={( )} disabled={!!editAction} // Disable in edit mode > {CONSTS.GOVERNABLE_STATES.map((s) => ( - + {s.label} + {!editAction && existingStates.includes(s.value) && ( + + + + )} ))} @@ -163,7 +179,7 @@ export default function ActionConfigDialog({ @@ -171,7 +187,7 @@ export default function ActionConfigDialog({ @@ -203,7 +219,8 @@ export default function ActionConfigDialog({ label={( {intl.formatMessage({ - id: 'Governance.Policies.AddEdit.action.notify', + id: 'Governance.Policies.AddEdit.enforcement.' + + 'action.notify', defaultMessage: 'Notify', })} @@ -215,7 +232,8 @@ export default function ActionConfigDialog({ label={( {intl.formatMessage({ - id: 'Governance.Policies.AddEdit.action.block', + id: 'Governance.Policies.AddEdit.enforcement.' + + 'action.block', defaultMessage: 'Block', })} @@ -234,7 +252,7 @@ export default function ActionConfigDialog({ @@ -246,7 +264,7 @@ export default function ActionConfigDialog({ size='small' > diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/AddEditPolicy.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/AddEditPolicy.jsx index 45847fd2ef3..2bfa7883dcd 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/AddEditPolicy.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/AddEditPolicy.jsx @@ -202,6 +202,30 @@ function AddEditPolicy(props) { editAction: null, }); + // Add this function inside the component before useEffect + const fetchAllRulesets = async (restApi, offset = 0, accumulator = []) => { + try { + const params = { + limit: 25, + offset, + }; + + const response = await restApi.getRulesets(params); + const { list, pagination } = response.body; + const newAccumulator = [...accumulator, ...list]; + + // If we haven't fetched all items yet, fetch the next page + if (pagination.total > offset + params.limit) { + return fetchAllRulesets(restApi, offset + params.limit, newAccumulator); + } + + return newAccumulator; + } catch (error) { + console.error('Error fetching rulesets:', error); + throw error; + } + }; + useEffect(() => { const restApi = new GovernanceAPI(); const adminApi = new API(); @@ -220,17 +244,17 @@ function AddEditPolicy(props) { })); }); - restApi.getRulesets() - .then((response) => { - const rulesetList = response.body.list; - setAvailableRulesets(rulesetList); + // Fetch all rulesets recursively + fetchAllRulesets(restApi) + .then((allRulesets) => { + setAvailableRulesets(allRulesets); if (policyId) { return restApi.getGovernancePolicyById(policyId) .then((policyResponse) => { const { body } = policyResponse; const fullRulesets = body.rulesets.map((rulesetId) => { - const foundRuleset = rulesetList.find((r) => r.id === rulesetId); + const foundRuleset = allRulesets.find((r) => r.id === rulesetId); return foundRuleset || { id: rulesetId, name: 'Unknown Ruleset' }; }); setSelectedRulesets(fullRulesets); @@ -447,32 +471,28 @@ function AddEditPolicy(props) { }; const groupActionsByState = (actionsList) => { - return actionsList.reduce((acc, action) => { - const existingStateIndex = acc.findIndex((item) => item.state === action.state); - if (existingStateIndex === -1) { - acc.push({ + // Create a map of all actions by state + const actionMap = actionsList.reduce((acc, action) => { + const existingState = acc.get(action.state); + if (!existingState) { + acc.set(action.state, { state: action.state, error: action.ruleSeverity === 'ERROR' ? action.type : null, warn: action.ruleSeverity === 'WARN' ? action.type : null, info: action.ruleSeverity === 'INFO' ? action.type : null, }); } else { - switch (action.ruleSeverity) { - case 'ERROR': - acc[existingStateIndex].error = action.type; - break; - case 'WARN': - acc[existingStateIndex].warn = action.type; - break; - case 'INFO': - acc[existingStateIndex].info = action.type; - break; - default: - break; - } + if (action.ruleSeverity === 'ERROR') existingState.error = action.type; + if (action.ruleSeverity === 'WARN') existingState.warn = action.type; + if (action.ruleSeverity === 'INFO') existingState.info = action.type; } return acc; - }, []); + }, new Map()); + + // Return array in GOVERNABLE_STATES order + return CONSTS.GOVERNABLE_STATES + .filter((st) => actionMap.has(st.value)) + .map((st) => actionMap.get(st.value)); }; const handleActionSave = (actionConfig) => { @@ -543,6 +563,17 @@ function AddEditPolicy(props) { setSelectedRulesets(selectedRulesets.filter((r) => r.id !== ruleset.id)); }; + // Get existing states from current actions + const getExistingStates = () => { + return [...new Set(actions.map((action) => action.state))]; + }; + + // Add this helper function to check if all states are configured + const areAllStatesConfigured = () => { + const existingStates = getExistingStates(); + return CONSTS.GOVERNABLE_STATES.every((st) => existingStates.includes(st.value)); + }; + return ( - + + + + {actions && actions.length > 0 && ( @@ -800,7 +845,7 @@ function AddEditPolicy(props) { {intl.formatMessage({ id: 'Governance.Policies.AddEdit.action.table.actions', - defaultMessage: 'Actions', + defaultMessage: 'Edit / Delete', })} @@ -992,6 +1037,7 @@ function AddEditPolicy(props) { onClose={handleCloseDialog} onSave={handleActionSave} editAction={dialogConfig.editAction} + existingStates={getExistingStates()} /> ); diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/DeletePolicy.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/DeletePolicy.jsx index 93513abe6a1..af724cdb345 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/DeletePolicy.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/DeletePolicy.jsx @@ -43,7 +43,19 @@ function DeletePolicy({ updateList, dataRow }) { /> )) .catch((error) => { - throw new Error(error.response.body.description); + const { response, message } = error; + if (response && response.body) { + Alert.error(response.body.description); + } else if (message) { + Alert.error(message); + } else { + Alert.error( + intl.formatMessage({ + id: 'AdminPages.Governance.Policy.Delete.form.delete.error', + defaultMessage: 'Something went wrong while deleting the Policy', + }) + ); + } }) .finally(() => { updateList(); diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ListPolicies.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ListPolicies.jsx index 1b83098598b..97a5c8aa4fb 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ListPolicies.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/Policies/ListPolicies.jsx @@ -16,7 +16,7 @@ * under the License. */ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { useIntl, FormattedMessage } from 'react-intl'; import Typography from '@mui/material/Typography'; import { @@ -31,36 +31,29 @@ import API from 'AppData/api'; import DeletePolicy from './DeletePolicy'; /** - * API call to get Policies - * @returns {Promise}. + * Get all policies recursively + * @param {Object} restApi GovernanceAPI instance + * @param {Array} accumulator Accumulated policies + * @returns {Promise} Promise resolving to all policies */ -function apiCall() { - const restApi = new GovernanceAPI(); - const adminApi = new API(); +async function getAllPolicies(restApi, accumulator = []) { + try { + const params = { + limit: 25, + offset: accumulator.length, + }; + const response = await restApi.getGovernancePolicies(params); + const { list, pagination } = response.body; + const newAccumulator = [...accumulator, ...list]; - // First get the labels - return adminApi.labelsListGet() - .then((labelsResponse) => { - const labelsList = labelsResponse.body.list || []; - // Get the policies - return restApi.getGovernancePolicies() - .then((result) => { - // Map label IDs to names - return result.body.list.map((policy) => { - return { - ...policy, - labels: policy.labels.map((labelId) => { - if (labelId === 'GLOBAL') return labelId; - const label = labelsList.find((l) => l.id === labelId); - return label ? label.name : labelId; - }), - }; - }); - }); - }) - .catch((error) => { - throw error; - }); + if (pagination.total > newAccumulator.length) { + return getAllPolicies(restApi, newAccumulator); + } + return newAccumulator; + } catch (error) { + console.error('Error fetching policies:', error); + throw error; + } } /** @@ -69,6 +62,35 @@ function apiCall() { */ export default function ListPolicies() { const intl = useIntl(); + const [policies, setPolicies] = useState(null); + + useEffect(() => { + const restApi = new GovernanceAPI(); + const adminApi = new API(); + + // First get all policies + getAllPolicies(restApi) + .then((allPolicies) => { + // Then get labels and map them + adminApi.labelsListGet() + .then((labelsResponse) => { + const labelsList = labelsResponse.body.list || []; + // Map label IDs to names + const policiesWithLabels = allPolicies.map((policy) => ({ + ...policy, + labels: policy.labels.map((labelId) => { + if (labelId === 'GLOBAL') return 'ALL'; + const label = labelsList.find((l) => l.id === labelId); + return label ? label.name : labelId; + }), + })); + setPolicies(policiesWithLabels); + }); + }) + .catch((error) => { + console.error('Error loading policies:', error); + }); + }, []); const columProps = [ { @@ -291,7 +313,7 @@ export default function ListPolicies() { addButtonProps={addButtonProps} searchProps={searchProps} emptyBoxProps={emptyBoxProps} - apiCall={apiCall} + initialData={policies} DeleteComponent={DeletePolicy} editComponentProps={{ icon: , diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/AddEditRuleset.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/AddEditRuleset.jsx index c508ed7e1dc..d03db62135b 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/AddEditRuleset.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/AddEditRuleset.jsx @@ -35,6 +35,7 @@ import { DialogContent, DialogActions, DialogContentText, + Alert as MuiAlert, } from '@mui/material'; import { styled } from '@mui/material/styles'; import Editor from '@monaco-editor/react'; @@ -93,6 +94,7 @@ function AddEditRuleset(props) { const [saving, setSaving] = useState(false); const [openConfirmDialog, setOpenConfirmDialog] = useState(false); const [pendingFile, setPendingFile] = useState(null); + const [rulesetValidationError, setRulesetValidationError] = useState(null); const intl = useIntl(); const { match: { params: { id } }, history } = props; @@ -311,6 +313,7 @@ function AddEditRuleset(props) { const formSave = () => { setValidating(true); + setRulesetValidationError(null); if (formHasErrors(true)) { Alert.error(intl.formatMessage({ id: 'Governance.Rulesets.AddEdit.form.has.errors', @@ -357,7 +360,12 @@ function AddEditRuleset(props) { }).catch((error) => { const { response, message } = error; if (response && response.body) { - Alert.error(response.body.description); + if (response.body.code === 990120) { + setRulesetValidationError(response.body.description); + Alert.error(response.body.message); + } else { + Alert.error(response.body.description); + } } else if (message) { Alert.error(message); } @@ -599,6 +607,13 @@ function AddEditRuleset(props) { {hasErrors('rulesetContent', rulesetContent, true)} )} + {rulesetValidationError && ( + + + {rulesetValidationError} + + + )} {/* Action Buttons */} diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/DeleteRuleset.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/DeleteRuleset.jsx index d8de713677e..8af52d0f903 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/DeleteRuleset.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/DeleteRuleset.jsx @@ -23,6 +23,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import DialogContentText from '@mui/material/DialogContentText'; import DeleteForeverIcon from '@mui/icons-material/DeleteForever'; import FormDialogBase from 'AppComponents/AdminPages/Addons/FormDialogBase'; +import Alert from 'AppComponents/Shared/Alert'; /** * Renders delete dialog box @@ -43,7 +44,19 @@ function DeleteRuleset({ updateList, dataRow }) { /> )) .catch((error) => { - throw new Error(error.response.body.description); + const { response, message } = error; + if (message) { + Alert.error(message); + } else if (response && response.body) { + Alert.error(response.body.description); + } else { + Alert.error( + intl.formatMessage({ + id: 'AdminPages.Governance.Ruleset.Delete.form.delete.error', + defaultMessage: 'Something went wrong while deleting the Ruleset', + }), + ); + } }) .finally(() => { updateList(); diff --git a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/ListRulesets.jsx b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/ListRulesets.jsx index f033d1b0dbc..2bbac694c2a 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/ListRulesets.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Governance/RulesetCatalog/ListRulesets.jsx @@ -16,7 +16,7 @@ * under the License. */ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { useIntl, FormattedMessage } from 'react-intl'; import Typography from '@mui/material/Typography'; import ListBase from 'AppComponents/AdminPages/Addons/ListBase'; @@ -28,19 +28,29 @@ import Utils from 'AppData/Utils'; import DeleteRuleset from './DeleteRuleset'; /** - * API call to get Rulesets - * @returns {Promise}. + * Get all rulesets recursively + * @param {Object} restApi GovernanceAPI instance + * @param {Array} accumulator Accumulated rulesets + * @returns {Promise} Promise resolving to all rulesets */ -function apiCall() { - const restApi = new GovernanceAPI(); - return restApi - .getRulesets() - .then((result) => { - return result.body.list; - }) - .catch((error) => { - throw error; - }); +async function getAllRulesets(restApi, accumulator = []) { + try { + const params = { + limit: 25, + offset: accumulator.length, + }; + const response = await restApi.getRulesets(params); + const { list, pagination } = response.body; + const newAccumulator = [...accumulator, ...list]; + + if (pagination.total > newAccumulator.length) { + return getAllRulesets(restApi, newAccumulator); + } + return newAccumulator; + } catch (error) { + console.error('Error fetching rulesets:', error); + throw error; + } } /** @@ -49,6 +59,18 @@ function apiCall() { */ export default function ListRulesets() { const intl = useIntl(); + const [rulesets, setRulesets] = useState(null); + + useEffect(() => { + const restApi = new GovernanceAPI(); + getAllRulesets(restApi) + .then((allRulesets) => { + setRulesets(allRulesets); + }) + .catch((error) => { + console.error('Error loading rulesets:', error); + }); + }, []); const columProps = [ { @@ -252,7 +274,7 @@ export default function ListRulesets() { }), active: true, }} - apiCall={apiCall} + initialData={rulesets} DeleteComponent={DeleteRuleset} editComponentProps={{ icon: , diff --git a/portals/admin/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx b/portals/admin/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx index 808fedf4b49..680d96234ee 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx @@ -52,6 +52,7 @@ const DonutChart = ({ colors={colors} series={[{ data, + valueFormatter: () => '', innerRadius: 50, outerRadius: 100, paddingAngle: 5, @@ -81,7 +82,7 @@ DonutChart.propTypes = { DonutChart.defaultProps = { height: 200, width: 400, - colors: ['#2E96FF', '#FF5252', 'grey'], + colors: ['#00B81D', '#FF5252', 'grey'], }; export default DonutChart; diff --git a/portals/admin/src/main/webapp/source/src/app/data/GovernanceAPI.js b/portals/admin/src/main/webapp/source/src/app/data/GovernanceAPI.js index 8dbf07489a4..f13848b62c1 100644 --- a/portals/admin/src/main/webapp/source/src/app/data/GovernanceAPI.js +++ b/portals/admin/src/main/webapp/source/src/app/data/GovernanceAPI.js @@ -78,11 +78,13 @@ class GovernanceAPI extends Resource { /** * Get list of governance policies + * @param {Object} [params] Optional query parameters for pagination (limit, offset) and searching * @returns {Promise} Promised policies response */ - getGovernancePolicies() { + getGovernancePolicies(params = {}) { return this.client.then((client) => { return client.apis['Governance Policies'].getGovernancePolicies( + params, this._requestMetaData(), ); }); @@ -150,14 +152,15 @@ class GovernanceAPI extends Resource { }); } - // rulesets /** * Get list of rulesets + * @param {Object} [params] Optional query parameters for pagination (limit, offset) and searching * @returns {Promise} Promised rulesets response */ - getRulesets() { + getRulesets(params = {}) { return this.client.then((client) => { return client.apis['Rulesets'].getRulesets( + params, this._requestMetaData(), ); }); diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/APICompliance/Compliance.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/APICompliance/Compliance.jsx index 0823679100c..fd212062cee 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/APICompliance/Compliance.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/APICompliance/Compliance.jsx @@ -242,7 +242,7 @@ export default function Compliance() { /> { )} {anyErrors && ( - <> - - + + {newSampleAPI && ( - + { )} - + )} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx index 808fedf4b49..884a8dfb7b7 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Shared/DonutChart.jsx @@ -52,6 +52,7 @@ const DonutChart = ({ colors={colors} series={[{ data, + valueFormatter: () => '', innerRadius: 50, outerRadius: 100, paddingAngle: 5,