diff --git a/cypress/e2e/awx/general-ui/dashboard-checks.cy.ts b/cypress/e2e/awx/general-ui/dashboard-checks.cy.ts
index 8eb11c9dd5..6805b73009 100644
--- a/cypress/e2e/awx/general-ui/dashboard-checks.cy.ts
+++ b/cypress/e2e/awx/general-ui/dashboard-checks.cy.ts
@@ -1,4 +1,5 @@
import { AwxItemsResponse } from '../../../../frontend/awx/common/AwxItemsResponse';
+import { IAwxDashboardData } from '../../../../frontend/awx/dashboard/AwxDashboard';
import { Inventory } from '../../../../frontend/awx/interfaces/Inventory';
import { Job } from '../../../../frontend/awx/interfaces/Job';
import { Project } from '../../../../frontend/awx/interfaces/Project';
@@ -30,33 +31,34 @@ describe('Dashboard: General UI tests - resources count and empty state check',
cy.visit(`/ui_next/dashboard`);
cy.clickButton('Manage view');
cy.get('.pf-c-modal-box__title-text').should('contain', 'Manage Dashboard');
- cy.contains('tr', 'Projects').find('input').uncheck();
+ cy.contains('tr', 'Resource Counts').find('input').uncheck();
cy.clickModalButton('Apply');
- cy.contains('.pf-c-card__header', 'Projects').should('not.be.visible');
+ cy.contains('.pf-c-title', 'Hosts').should('not.exist');
cy.clickButton('Manage view');
cy.get('.pf-c-modal-box__title-text').should('contain', 'Manage Dashboard');
- cy.contains('tr', 'Projects').find('input').check();
+ cy.contains('tr', 'Resource Counts').find('input').check();
cy.clickModalButton('Apply');
- cy.contains('.pf-c-card__header', 'Projects').should('be.visible');
+ cy.contains('.pf-c-title', 'Hosts').should('be.visible');
});
it('within the Manage Dashboard modal, clicking the Cancel button should revert any changes', () => {
cy.visit(`/ui_next/dashboard`);
cy.clickButton('Manage view');
cy.get('.pf-c-modal-box__title-text').should('contain', 'Manage Dashboard');
- cy.contains('tr', 'Projects').find('input').uncheck();
+ cy.contains('tr', 'Resource Counts').find('input').uncheck();
cy.clickModalButton('Cancel');
- cy.contains('.pf-c-card__header', 'Projects').should('be.visible');
+ cy.contains('.pf-c-title', 'Hosts').should('be.visible');
});
it('within the Manage Dashboard modal, clicking the Close button should revert any changes', () => {
cy.visit(`/ui_next/dashboard`);
cy.clickButton('Manage view');
cy.get('.pf-c-modal-box__title-text').should('contain', 'Manage Dashboard');
- cy.contains('tr', 'Projects').find('input').uncheck();
+ cy.contains('tr', 'Resource Counts').find('input').uncheck();
cy.get('[aria-label="Close"]').click();
- cy.contains('.pf-c-card__header', 'Projects').should('be.visible');
+ cy.contains('.pf-c-title', 'Hosts').should('be.visible');
});
+
// Manage Dashboard modal table does not currently support keyboard input to reorder items, use drag & drop
it('within the Manage Dashboard modal, dragging a resource should reorder the resource', () => {
let initialArray: string[];
@@ -67,7 +69,7 @@ describe('Dashboard: General UI tests - resources count and empty state check',
initialArray = Array.from(headers, (title) => title.innerText.split('\n')[0]);
cy.clickButton('Manage view');
cy.get('.pf-c-modal-box__title-text').should('contain', 'Manage Dashboard');
- cy.get('#draggable-row-project').drag('#draggable-row-recent_job_activity');
+ cy.get('#draggable-row-recent_jobs').drag('#draggable-row-recent_job_activity');
cy.clickModalButton('Apply');
});
cy.get('.pf-c-card__header').then((headers) => {
@@ -77,62 +79,58 @@ describe('Dashboard: General UI tests - resources count and empty state check',
});
it('checks inventories count', () => {
- cy.intercept('GET', 'api/v2/dashboard/').as('getInventories');
+ cy.intercept('GET', 'api/v2/dashboard/').as('getDashboard');
cy.visit(`/ui_next/dashboard`);
- cy.contains('.pf-c-card__header', 'Inventories')
- .next()
- .within(() => {
- cy.contains('tspan', 'Ready')
- .invoke('text')
- .then((text: string) => {
- cy.wait('@getInventories')
- .its('response.body.inventories.total')
- .then((total) => {
- expect(total).to.equal(parseInt(text.split(':')[1]));
- });
- });
+ cy.wait('@getDashboard')
+ .its('response.body')
+ .then((data: IAwxDashboardData) => {
+ cy.get('#inventories-chart').should('contain', data.inventories.total);
+ const readyCount = data.inventories.total - data.inventories.inventory_failed;
+ if (readyCount > 0) {
+ cy.get('#inventories-legend-synced-count').should('contain', readyCount);
+ }
+ if (data.inventories.inventory_failed > 0) {
+ cy.get('#inventories-legend-failed-count').should(
+ 'contain',
+ data.inventories.inventory_failed
+ );
+ }
});
- cy.checkAnchorLinks('Go to Inventories');
});
it('checks hosts count', () => {
- cy.intercept('GET', 'api/v2/dashboard/').as('getHosts');
+ cy.intercept('GET', 'api/v2/dashboard/').as('getDashboard');
cy.visit(`/ui_next/dashboard`);
- cy.contains('.pf-c-card__header', 'Hosts')
- .next()
- .within(() => {
- cy.contains('tspan', 'Ready')
- .invoke('text')
- .then((text: string) => {
- cy.wait('@getHosts')
- .its('response.body.hosts.total')
- .then((total) => {
- expect(total).to.equal(parseInt(text.split(':')[1]));
- });
- });
+ cy.wait('@getDashboard')
+ .its('response.body')
+ .then((data: IAwxDashboardData) => {
+ cy.get('#hosts-chart').should('contain', data.hosts.total);
+ const readyCount = data.hosts.total - data.hosts.failed;
+ if (readyCount > 0) {
+ cy.get('#hosts-legend-ready-count').should('contain', readyCount);
+ }
+ if (data.hosts.failed > 0) {
+ cy.get('#hosts-legend-failed-count').should('contain', data.hosts.failed);
+ }
});
- cy.checkAnchorLinks('Go to Hosts');
});
- // JT Disabling invalid test. Ready count does not always match the total count.
- // it('checks projects count', () => {
- // cy.intercept('GET', 'api/v2/dashboard/').as('getProjects');
- // cy.visit(`/ui_next/dashboard`);
- // cy.contains('.pf-c-card__header', 'Projects')
- // .next()
- // .within(() => {
- // cy.contains('tspan', 'Ready')
- // .invoke('text')
- // .then((text: string) => {
- // cy.wait('@getProjects')
- // .its('response.body.projects.total')
- // .then((total) => {
- // expect(total).to.equal(parseInt(text.split(':')[1]));
- // });
- // });
- // });
- // cy.checkAnchorLinks('Go to Projects');
- // });
+ it('checks projects count', () => {
+ cy.intercept('GET', 'api/v2/dashboard/').as('getDashboard');
+ cy.visit(`/ui_next/dashboard`);
+ cy.wait('@getDashboard')
+ .its('response.body')
+ .then((data: IAwxDashboardData) => {
+ cy.get('#projects-chart').should('contain', data.projects.total);
+ const readyCount = data.projects.total - data.projects.failed;
+ if (readyCount > 0) {
+ cy.get('#projects-legend-ready-count').should('contain', readyCount);
+ }
+ if (data.projects.failed > 0) {
+ cy.get('#projects-legend-failed-count').should('contain', data.projects.failed);
+ }
+ });
+ });
it('checks jobs count and the max # of jobs in the table', () => {
cy.intercept('GET', '/api/v2/unified_jobs/?order_by=-finished&page=1&page_size=10').as(
diff --git a/cypress/support/component.tsx b/cypress/support/component.tsx
index 874d16c369..74bf01e191 100644
--- a/cypress/support/component.tsx
+++ b/cypress/support/component.tsx
@@ -15,6 +15,9 @@
// ***********************************************************
import '@patternfly/patternfly/patternfly-base.css';
+import '@patternfly/patternfly/patternfly-charts.css';
+
+import '@patternfly/patternfly/patternfly-charts-theme-dark.css';
import { Page } from '@patternfly/react-core';
import 'cypress-react-selector';
diff --git a/framework/PageDashboard/PageDashboardCountBar.tsx b/framework/PageDashboard/PageDashboardCountBar.tsx
index a0c30377ed..b1d1be6914 100644
--- a/framework/PageDashboard/PageDashboardCountBar.tsx
+++ b/framework/PageDashboard/PageDashboardCountBar.tsx
@@ -1,13 +1,15 @@
-import { CardBody, Flex, FlexItem, Title } from '@patternfly/react-core';
-import { ArrowRightIcon } from '@patternfly/react-icons';
+import { ChartDonut, ChartLabel, ChartLabelProps } from '@patternfly/react-charts';
+import { CardBody, Title } from '@patternfly/react-core';
+import { CSSProperties } from 'react';
import { Link } from 'react-router-dom';
import { PageDashboardCard } from './PageDashboardCard';
export type PageDashboardCountBarProps = {
counts: {
title: string;
- count: number;
+ total?: number;
to: string;
+ counts?: { label: string; count: number; color: string; link?: string }[];
}[];
};
@@ -15,35 +17,143 @@ export function PageDashboardCountBar(props: PageDashboardCountBarProps) {
return (