mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 15:36:04 -03:30
Merge pull request #6444 from mabashian/ui-next-accessibility-low-hanging-fruitz
Adds aria-label to some buttons without text Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -81,7 +81,11 @@ function JobListItem({
|
|||||||
<Tooltip content={i18n._(t`Relaunch Job`)} position="top">
|
<Tooltip content={i18n._(t`Relaunch Job`)} position="top">
|
||||||
<LaunchButton resource={job}>
|
<LaunchButton resource={job}>
|
||||||
{({ handleRelaunch }) => (
|
{({ handleRelaunch }) => (
|
||||||
<Button variant="plain" onClick={handleRelaunch}>
|
<Button
|
||||||
|
variant="plain"
|
||||||
|
onClick={handleRelaunch}
|
||||||
|
aria-label={i18n._(t`Relaunch`)}
|
||||||
|
>
|
||||||
<RocketIcon />
|
<RocketIcon />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -72,7 +72,10 @@ class PageHeaderToolbar extends Component {
|
|||||||
position={DropdownPosition.right}
|
position={DropdownPosition.right}
|
||||||
onSelect={this.handleHelpSelect}
|
onSelect={this.handleHelpSelect}
|
||||||
toggle={
|
toggle={
|
||||||
<DropdownToggle onToggle={this.handleHelpToggle}>
|
<DropdownToggle
|
||||||
|
onToggle={this.handleHelpToggle}
|
||||||
|
aria-label={i18n._(t`Info`)}
|
||||||
|
>
|
||||||
<QuestionCircleIcon />
|
<QuestionCircleIcon />
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ function ScheduleListItem({ i18n, isSelected, onSelect, schedule }) {
|
|||||||
{schedule.summary_fields.user_capabilities.edit ? (
|
{schedule.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Schedule`)} position="top">
|
<Tooltip content={i18n._(t`Edit Schedule`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Schedule`)}
|
||||||
css="grid-column: 2"
|
css="grid-column: 2"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ const Sparkline = ({ i18n, jobs }) => {
|
|||||||
|
|
||||||
const statusIcons = jobs.map(job => (
|
const statusIcons = jobs.map(job => (
|
||||||
<Tooltip position="top" content={generateTooltip(job)} key={job.id}>
|
<Tooltip position="top" content={generateTooltip(job)} key={job.id}>
|
||||||
<Link to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}>
|
<Link
|
||||||
|
aria-label={i18n._(t`View job ${job.id}`)}
|
||||||
|
to={`/jobs/${JOB_TYPE_URL_SEGMENTS[job.type]}/${job.id}`}
|
||||||
|
>
|
||||||
<StatusIcon status={job.status} />
|
<StatusIcon status={job.status} />
|
||||||
</Link>
|
</Link>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ function CredentialListItem({
|
|||||||
{canEdit ? (
|
{canEdit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Credential`)} position="top">
|
<Tooltip content={i18n._(t`Edit Credential`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Credential`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/credentials/${credential.id}/edit`}
|
to={`/credentials/${credential.id}/edit`}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ function HostListItem({ i18n, host, isSelected, onSelect, detailUrl }) {
|
|||||||
{host.summary_fields.user_capabilities.edit ? (
|
{host.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Host`)} position="top">
|
<Tooltip content={i18n._(t`Edit Host`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Host`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/hosts/${host.id}/edit`}
|
to={`/hosts/${host.id}/edit`}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ function InventoryGroupHostListItem({
|
|||||||
{host.summary_fields.user_capabilities?.edit && (
|
{host.summary_fields.user_capabilities?.edit && (
|
||||||
<Tooltip content={i18n._(t`Edit Host`)} position="top">
|
<Tooltip content={i18n._(t`Edit Host`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Host`)}
|
||||||
css="grid-column: 2"
|
css="grid-column: 2"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -54,7 +54,12 @@ function InventoryGroupItem({
|
|||||||
>
|
>
|
||||||
{group.summary_fields.user_capabilities.edit && (
|
{group.summary_fields.user_capabilities.edit && (
|
||||||
<Tooltip content={i18n._(t`Edit Group`)} position="top">
|
<Tooltip content={i18n._(t`Edit Group`)} position="top">
|
||||||
<Button variant="plain" component={Link} to={editUrl}>
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Group`)}
|
||||||
|
variant="plain"
|
||||||
|
component={Link}
|
||||||
|
to={editUrl}
|
||||||
|
>
|
||||||
<PencilAltIcon />
|
<PencilAltIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ class InventoryListItem extends React.Component {
|
|||||||
{inventory.summary_fields.user_capabilities.edit ? (
|
{inventory.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Inventory`)} position="top">
|
<Tooltip content={i18n._(t`Edit Inventory`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Inventory`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/inventories/${
|
to={`/inventories/${
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ async function checkOutput(wrapper, expectedLines) {
|
|||||||
async function findScrollButtons(wrapper) {
|
async function findScrollButtons(wrapper) {
|
||||||
const pageControls = await waitForElement(wrapper, 'PageControls');
|
const pageControls = await waitForElement(wrapper, 'PageControls');
|
||||||
const scrollFirstButton = pageControls.find(
|
const scrollFirstButton = pageControls.find(
|
||||||
'button[aria-label="scroll first"]'
|
'button[aria-label="Scroll first"]'
|
||||||
);
|
);
|
||||||
const scrollLastButton = pageControls.find(
|
const scrollLastButton = pageControls.find(
|
||||||
'button[aria-label="scroll last"]'
|
'button[aria-label="Scroll last"]'
|
||||||
);
|
);
|
||||||
const scrollPreviousButton = pageControls.find(
|
const scrollPreviousButton = pageControls.find(
|
||||||
'button[aria-label="scroll previous"]'
|
'button[aria-label="Scroll previous"]'
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
scrollFirstButton,
|
scrollFirstButton,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { withI18n } from '@lingui/react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
import { Button as PFButton } from '@patternfly/react-core';
|
import { Button as PFButton } from '@patternfly/react-core';
|
||||||
import {
|
import {
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
@@ -22,32 +24,49 @@ const Button = styled(PFButton)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const PageControls = ({
|
const PageControls = ({
|
||||||
|
i18n,
|
||||||
onScrollFirst,
|
onScrollFirst,
|
||||||
onScrollLast,
|
onScrollLast,
|
||||||
onScrollNext,
|
onScrollNext,
|
||||||
onScrollPrevious,
|
onScrollPrevious,
|
||||||
}) => (
|
}) => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Button variant="plain" css="margin-right: auto">
|
<Button
|
||||||
|
aria-label={i18n._(t`Toggle expand/collapse event lines`)}
|
||||||
|
variant="plain"
|
||||||
|
css="margin-right: auto"
|
||||||
|
>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
aria-label="scroll previous"
|
aria-label={i18n._(t`Scroll previous`)}
|
||||||
onClick={onScrollPrevious}
|
onClick={onScrollPrevious}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
>
|
>
|
||||||
<AngleUpIcon />
|
<AngleUpIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button aria-label="scroll next" onClick={onScrollNext} variant="plain">
|
<Button
|
||||||
|
aria-label={i18n._(t`Scroll next`)}
|
||||||
|
onClick={onScrollNext}
|
||||||
|
variant="plain"
|
||||||
|
>
|
||||||
<AngleDownIcon />
|
<AngleDownIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button aria-label="scroll first" onClick={onScrollFirst} variant="plain">
|
<Button
|
||||||
|
aria-label={i18n._(t`Scroll first`)}
|
||||||
|
onClick={onScrollFirst}
|
||||||
|
variant="plain"
|
||||||
|
>
|
||||||
<AngleDoubleUpIcon />
|
<AngleDoubleUpIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<Button aria-label="scroll last" onClick={onScrollLast} variant="plain">
|
<Button
|
||||||
|
aria-label={i18n._(t`Scroll last`)}
|
||||||
|
onClick={onScrollLast}
|
||||||
|
variant="plain"
|
||||||
|
>
|
||||||
<AngleDoubleDownIcon />
|
<AngleDoubleDownIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default PageControls;
|
export default withI18n()(PageControls);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||||
import PageControls from './PageControls';
|
import PageControls from './PageControls';
|
||||||
|
|
||||||
let wrapper;
|
let wrapper;
|
||||||
@@ -19,12 +19,12 @@ const findChildren = () => {
|
|||||||
|
|
||||||
describe('PageControls', () => {
|
describe('PageControls', () => {
|
||||||
test('should render successfully', () => {
|
test('should render successfully', () => {
|
||||||
wrapper = mount(<PageControls />);
|
wrapper = mountWithContexts(<PageControls />);
|
||||||
expect(wrapper).toHaveLength(1);
|
expect(wrapper).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render menu control icons', () => {
|
test('should render menu control icons', () => {
|
||||||
wrapper = mount(<PageControls />);
|
wrapper = mountWithContexts(<PageControls />);
|
||||||
findChildren();
|
findChildren();
|
||||||
expect(PlusIcon.length).toBe(1);
|
expect(PlusIcon.length).toBe(1);
|
||||||
expect(AngleDoubleUpIcon.length).toBe(1);
|
expect(AngleDoubleUpIcon.length).toBe(1);
|
||||||
|
|||||||
@@ -127,7 +127,11 @@ const OutputToolbar = ({ i18n, job, onDelete }) => {
|
|||||||
<Tooltip content={i18n._(t`Relaunch Job`)}>
|
<Tooltip content={i18n._(t`Relaunch Job`)}>
|
||||||
<LaunchButton resource={job} aria-label={i18n._(t`Relaunch`)}>
|
<LaunchButton resource={job} aria-label={i18n._(t`Relaunch`)}>
|
||||||
{({ handleRelaunch }) => (
|
{({ handleRelaunch }) => (
|
||||||
<Button variant="plain" onClick={handleRelaunch}>
|
<Button
|
||||||
|
variant="plain"
|
||||||
|
onClick={handleRelaunch}
|
||||||
|
aria-label={i18n._(t`Relaunch`)}
|
||||||
|
>
|
||||||
<RocketIcon />
|
<RocketIcon />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -138,7 +142,7 @@ const OutputToolbar = ({ i18n, job, onDelete }) => {
|
|||||||
{job.related?.stdout && (
|
{job.related?.stdout && (
|
||||||
<Tooltip content={i18n._(t`Download Output`)}>
|
<Tooltip content={i18n._(t`Download Output`)}>
|
||||||
<a href={`${job.related.stdout}?format=txt_download`}>
|
<a href={`${job.related.stdout}?format=txt_download`}>
|
||||||
<Button variant="plain">
|
<Button variant="plain" aria-label={i18n._(t`Download Output`)}>
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ function OrganizationListItem({
|
|||||||
{organization.summary_fields.user_capabilities.edit ? (
|
{organization.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Organization`)} position="top">
|
<Tooltip content={i18n._(t`Edit Organization`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Organization`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/organizations/${organization.id}/edit`}
|
to={`/organizations/${organization.id}/edit`}
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ class ProjectListItem extends React.Component {
|
|||||||
<ProjectSyncButton projectId={project.id}>
|
<ProjectSyncButton projectId={project.id}>
|
||||||
{handleSync => (
|
{handleSync => (
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Sync Project`)}
|
||||||
css="grid-column: 1"
|
css="grid-column: 1"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
onClick={handleSync}
|
onClick={handleSync}
|
||||||
@@ -147,6 +148,7 @@ class ProjectListItem extends React.Component {
|
|||||||
{project.summary_fields.user_capabilities.edit ? (
|
{project.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Project`)} position="top">
|
<Tooltip content={i18n._(t`Edit Project`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Project`)}
|
||||||
css="grid-column: 2"
|
css="grid-column: 2"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class TeamListItem extends React.Component {
|
|||||||
{team.summary_fields.user_capabilities.edit ? (
|
{team.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Team`)} position="top">
|
<Tooltip content={i18n._(t`Edit Team`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Team`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/teams/${team.id}/edit`}
|
to={`/teams/${team.id}/edit`}
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ function TemplateListItem({ i18n, template, isSelected, onSelect, detailUrl }) {
|
|||||||
<LaunchButton resource={template}>
|
<LaunchButton resource={template}>
|
||||||
{({ handleLaunch }) => (
|
{({ handleLaunch }) => (
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Launch template`)}
|
||||||
css="grid-column: 1"
|
css="grid-column: 1"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
onClick={handleLaunch}
|
onClick={handleLaunch}
|
||||||
@@ -102,6 +103,7 @@ function TemplateListItem({ i18n, template, isSelected, onSelect, detailUrl }) {
|
|||||||
{template.summary_fields.user_capabilities.edit ? (
|
{template.summary_fields.user_capabilities.edit ? (
|
||||||
<Tooltip content={i18n._(t`Edit Template`)} position="top">
|
<Tooltip content={i18n._(t`Edit Template`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit Template`)}
|
||||||
css="grid-column: 2"
|
css="grid-column: 2"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ class UserListItem extends React.Component {
|
|||||||
{user.summary_fields.user_capabilities.edit && (
|
{user.summary_fields.user_capabilities.edit && (
|
||||||
<Tooltip content={i18n._(t`Edit User`)} position="top">
|
<Tooltip content={i18n._(t`Edit User`)} position="top">
|
||||||
<Button
|
<Button
|
||||||
|
aria-label={i18n._(t`Edit User`)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/users/${user.id}/edit`}
|
to={`/users/${user.id}/edit`}
|
||||||
|
|||||||
Reference in New Issue
Block a user