diff --git a/awx/ui_next/.eslintrc b/awx/ui_next/.eslintrc index a648085d46..90c96ae87b 100644 --- a/awx/ui_next/.eslintrc +++ b/awx/ui_next/.eslintrc @@ -60,6 +60,7 @@ "mode", "aria-labelledby", "aria-hidden", + "aria-controls", "sortKey", "ouiaId", "credentialTypeNamespace", diff --git a/awx/ui_next/src/components/AppContainer/AppContainer.jsx b/awx/ui_next/src/components/AppContainer/AppContainer.jsx index 4c290adb41..ede56b2862 100644 --- a/awx/ui_next/src/components/AppContainer/AppContainer.jsx +++ b/awx/ui_next/src/components/AppContainer/AppContainer.jsx @@ -138,10 +138,13 @@ function AppContainer({ i18n, navRouteConfig = [], children }) { } }, [handleLogout, timeRemaining]); + const brandName = config?.license_info?.product_name; + const alt = brandName ? i18n._(t`${brandName} logo`) : i18n._(t`brand logo`); + const header = ( } + logo={} logoProps={{ href: '/' }} headerTools={ } + logo={} headerTools={ diff --git a/awx/ui_next/src/components/AppContainer/BrandLogo.jsx b/awx/ui_next/src/components/AppContainer/BrandLogo.jsx index be15af6773..1c8667b65d 100644 --- a/awx/ui_next/src/components/AppContainer/BrandLogo.jsx +++ b/awx/ui_next/src/components/AppContainer/BrandLogo.jsx @@ -13,6 +13,8 @@ const BrandImg = styled.img` pointer-events: none; `; -const BrandLogo = () => ; +const BrandLogo = ({ alt }) => ( + +); export default BrandLogo; diff --git a/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx b/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx index fac99894f4..501ece5bdb 100644 --- a/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx +++ b/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx @@ -96,11 +96,15 @@ function CodeEditor({ useEffect( function removeTextareaTabIndex() { const editorInput = editor.current.refEditor?.querySelector('textarea'); - if (editorInput && !readOnly) { + if (!editorInput) { + return; + } + if (!readOnly) { editorInput.tabIndex = -1; } + editorInput.id = id; }, - [readOnly] + [readOnly, id] ); const listen = useCallback(event => { @@ -144,7 +148,7 @@ function CodeEditor({ value={value} onFocus={onFocus} onBlur={onBlur} - name={id || 'code-editor'} + name={`${id}-editor` || 'code-editor'} editorProps={{ $blockScrolling: true }} fontSize={16} width="100%" diff --git a/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx b/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx index 5063ab033f..beda9dcacd 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesDetail.jsx @@ -73,6 +73,7 @@ function VariablesDetail({ css="grid-column: 1 / -1" >
-
+
+
', () => { expect(input2.prop('value')).toEqual('---foo: bar'); }); - test('should render label and value= --- when there are no values', () => { + test('should render label and value --- when there are no values', () => { const wrapper = mountWithContexts( ); expect(wrapper.find('VariablesDetail___StyledCodeEditor').length).toBe(1); - expect(wrapper.find('div.pf-c-form__label').text()).toBe('Variables'); + expect(wrapper.find('.pf-c-form__label').text()).toBe('Variables'); }); test('should update value if prop changes', () => { diff --git a/awx/ui_next/src/components/CodeEditor/VariablesField.jsx b/awx/ui_next/src/components/CodeEditor/VariablesField.jsx index 58e9960b82..aec4e4824f 100644 --- a/awx/ui_next/src/components/CodeEditor/VariablesField.jsx +++ b/awx/ui_next/src/components/CodeEditor/VariablesField.jsx @@ -203,7 +203,7 @@ function VariablesFieldInternals({ - {tooltip && } + {tooltip && } { )} ); - expect(wrapper.find('Popover[data-cy="the-field"]').length).toBe(1); + expect(wrapper.find('Popover[data-cy="the-field-tooltip"]').length).toBe(1); }); it('should submit value through Formik', async () => { diff --git a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx index 8c9051e67e..4617d0284c 100644 --- a/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx +++ b/awx/ui_next/src/components/FieldWithPrompt/FieldWithPrompt.jsx @@ -39,7 +39,7 @@ function FieldWithPrompt({ )} - {tooltip && } + {tooltip && }
{ ); expect(wrapper.find('.pf-c-form__label-required')).toHaveLength(1); - expect(wrapper.find('Popover[data-cy="job-template-limit"]').length).toBe( - 1 - ); + expect( + wrapper.find('Popover[data-cy="job-template-limit-tooltip"]').length + ).toBe(1); }); }); diff --git a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx index 473db38932..f75841f40b 100644 --- a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx +++ b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import { func, string } from 'prop-types'; +import { t } from '@lingui/macro'; import { Select, SelectOption, SelectVariant } from '@patternfly/react-core'; import { arrayToString, stringToArray } from '../../util/strings'; @@ -51,7 +52,7 @@ function TagMultiSelect({ onChange, value }) { }} selections={selections} isOpen={isExpanded} - aria-labelledby="tag-select" + typeAheadAriaLabel={t`Select tags`} > {renderOptions(options)} diff --git a/awx/ui_next/src/components/PaginatedTable/PaginatedTable.jsx b/awx/ui_next/src/components/PaginatedTable/PaginatedTable.jsx index 2d33fe1e66..ffd9878d60 100644 --- a/awx/ui_next/src/components/PaginatedTable/PaginatedTable.jsx +++ b/awx/ui_next/src/components/PaginatedTable/PaginatedTable.jsx @@ -123,6 +123,9 @@ function PaginatedTable({ } onSetPage={handleSetPage} onPerPageSelect={handleSetPageSize} + titles={{ + paginationTitle: t`Top Pagination`, + }} /> ); diff --git a/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx b/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx index c995404ddd..b29f0b9896 100644 --- a/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx +++ b/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx @@ -3,8 +3,7 @@ import { shape, string, number, arrayOf, node, oneOfType } from 'prop-types'; import { Tab, Tabs, TabTitleText } from '@patternfly/react-core'; import { useHistory, useLocation } from 'react-router-dom'; -function RoutedTabs(props) { - const { tabsArray } = props; +function RoutedTabs({ tabsArray }) { const history = useHistory(); const location = useLocation(); @@ -33,12 +32,12 @@ function RoutedTabs(props) { {tabsArray.map(tab => ( {tab.name}} - role="tab" + aria-controls="" /> ))} diff --git a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx index ccf5fa8855..394128a095 100644 --- a/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx +++ b/awx/ui_next/src/components/Schedule/ScheduleList/ScheduleListItem.test.jsx @@ -50,13 +50,17 @@ describe('ScheduleListItem', () => { describe('User has edit permissions', () => { beforeAll(() => { wrapper = mountWithContexts( - + + + + +
); }); @@ -190,22 +194,26 @@ describe('ScheduleListItem', () => { describe('schedule has missing prompt data', () => { beforeAll(() => { wrapper = mountWithContexts( - + + + + +
); }); diff --git a/awx/ui_next/src/components/Search/Search.jsx b/awx/ui_next/src/components/Search/Search.jsx index 2c38f98793..31478f8b81 100644 --- a/awx/ui_next/src/components/Search/Search.jsx +++ b/awx/ui_next/src/components/Search/Search.jsx @@ -175,6 +175,7 @@ function Search({ variant={SelectVariant.single} className="simpleKeySelect" aria-label={i18n._(t`Simple key select`)} + typeAheadAriaLabel={i18n._(t`Simple key select`)} onToggle={setIsSearchDropdownOpen} onSelect={handleDropdownSelect} selections={searchColumnName} @@ -212,6 +213,7 @@ function Search({ {i18n._(t`Job status`)}} - /> + > + + + + + + + + + + + + {i18n._(t`Recent Jobs`)}} - /> + > +
+ {activeTabId === 1 && ( + + )} +
+
{i18n._(t`Recent Templates`)} } - /> + > +
+ {activeTabId === 2 && ( + + )} +
+
- {activeTabId === 0 && ( - - - - - - - - - - - - )} - {activeTabId === 1 && } - {activeTabId === 2 && ( - - )} diff --git a/awx/ui_next/src/screens/Dashboard/shared/LineChart.jsx b/awx/ui_next/src/screens/Dashboard/shared/LineChart.jsx index 922605a3ad..cebd59c7a3 100644 --- a/awx/ui_next/src/screens/Dashboard/shared/LineChart.jsx +++ b/awx/ui_next/src/screens/Dashboard/shared/LineChart.jsx @@ -248,7 +248,7 @@ function LineChart({ id, data, height, i18n, pageContext }) { .style('fill', () => colors(0)) .attr('cx', d => x(d.DATE)) .attr('cy', d => y(d.FAIL)) - .attr('id', d => `success-dot-${dateFormat(d.DATE)}`) + .attr('id', d => `fail-dot-${dateFormat(d.DATE)}`) .on('mouseover', handleMouseOver) .on('mousemove', handleMouseMove) .on('mouseout', handleMouseOut); diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.test.jsx similarity index 100% rename from awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnviromentList.test.jsx rename to awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentList.test.jsx diff --git a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx index ab38b3e00a..05655925f4 100644 --- a/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx +++ b/awx/ui_next/src/screens/ExecutionEnvironment/ExecutionEnvironmentList/ExecutionEnvironmentListItem.jsx @@ -43,8 +43,6 @@ function ExecutionEnvironmentListItem({ setIsDisabled(false); }, []); - const labelId = `check-action-${executionEnvironment.id}`; - return ( - + {executionEnvironment.name} - - {executionEnvironment.image} - - + {executionEnvironment.image} + {executionEnvironment.organization ? ( { sourcePathHelpers.setValue(value); }} aria-label={i18n._(t`Select source path`)} + typeAheadAriaLabel={i18n._(t`Select source path`)} placeholder={i18n._(t`Select source path`)} createText={i18n._(t`Set source path to`)} isCreatable diff --git a/awx/ui_next/src/screens/Project/ProjectList/ProjectListItem.jsx b/awx/ui_next/src/screens/Project/ProjectList/ProjectListItem.jsx index 55c265cf0d..b9c902c4a8 100644 --- a/awx/ui_next/src/screens/Project/ProjectList/ProjectListItem.jsx +++ b/awx/ui_next/src/screens/Project/ProjectList/ProjectListItem.jsx @@ -98,7 +98,7 @@ function ProjectListItem({ /> - + {project.name} diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx index 1b1086e6b2..0a1e57d0c9 100644 --- a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx +++ b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx @@ -88,6 +88,7 @@ function SurveyPreviewModal({ id={`survey-preview-multipleChoice-${q.variable}`} isDisabled aria-label={i18n._(t`Multiple Choice`)} + typeAheadAriaLabel={i18n._(t`Multiple Choice`)} placeholderText={q.default} onToggle={() => {}} /> @@ -109,6 +110,7 @@ function SurveyPreviewModal({ } onToggle={() => {}} aria-label={i18n._(t`Multi-Select`)} + typeAheadAriaLabel={i18n._(t`Multi-Select`)} id={`survey-preview-multiSelect-${q.variable}`} > {q.choices.length > 0 && diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx index 3ae4894e85..59d0872826 100644 --- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx +++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx @@ -239,6 +239,7 @@ function NodeTypeStep({ i18n }) { setIsConvergenceOpen(false); }} aria-label={i18n._(t`Convergence select`)} + typeAheadAriaLabel={i18n._(t`Convergence select`)} className="convergenceSelect" ouiaId="convergenceSelect" > diff --git a/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx b/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx index 539947738f..5bd8da9add 100644 --- a/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx +++ b/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { func, arrayOf, number, shape, string, oneOfType } from 'prop-types'; import { Select, SelectOption, SelectVariant } from '@patternfly/react-core'; +import { t } from '@lingui/macro'; import { LabelsAPI } from '../../../api'; import { useSyncedSelectValue } from '../../../components/MultiSelect'; @@ -84,7 +85,7 @@ function LabelSelect({ value, placeholder, onChange, onError, createText }) { isDisabled={isLoading} selections={selections} isOpen={isExpanded} - aria-labelledby="label-select" + typeAheadAriaLabel={t`Select Labels`} placeholderText={placeholder} createText={createText} > diff --git a/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx b/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx index ad47f2d4c1..313a89fb40 100644 --- a/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx +++ b/awx/ui_next/src/screens/Template/shared/PlaybookSelect.jsx @@ -56,6 +56,7 @@ function PlaybookSelect({ selections={selected} onToggle={setIsOpen} placeholderText={i18n._(t`Select a playbook`)} + typeAheadAriaLabel={i18n._(t`Select a playbook`)} isCreateable={false} onSelect={(event, value) => { setIsOpen(false); diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx index a1891d26f0..6ee8446415 100644 --- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx +++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.jsx @@ -159,7 +159,7 @@ function WorkflowJobTemplateForm({ )} { scmHelpers.setValue(value); diff --git a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx index ccea65a8b9..f1e81f2fd6 100644 --- a/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx +++ b/awx/ui_next/src/screens/Template/shared/WorkflowJobTemplateForm.test.jsx @@ -226,22 +226,14 @@ describe('', () => { test('test changes in FieldWithPrompt', async () => { await act(async () => { - wrapper.find('TextInputBase#text-wfjt-scm-branch').prop('onChange')( - 'main' - ); - wrapper.find('TextInputBase#text-wfjt-limit').prop('onChange')( - 1234567890 - ); + wrapper.find('TextInputBase#wfjt-scm-branch').prop('onChange')('main'); + wrapper.find('TextInputBase#wfjt-limit').prop('onChange')(1234567890); }); wrapper.update(); - expect(wrapper.find('input#text-wfjt-scm-branch').prop('value')).toEqual( - 'main' - ); - expect(wrapper.find('input#text-wfjt-limit').prop('value')).toEqual( - 1234567890 - ); + expect(wrapper.find('input#wfjt-scm-branch').prop('value')).toEqual('main'); + expect(wrapper.find('input#wfjt-limit').prop('value')).toEqual(1234567890); }); test('webhooks and enable concurrent jobs functions properly', async () => { diff --git a/awx/ui_next/src/screens/User/UserList/UserListItem.jsx b/awx/ui_next/src/screens/User/UserList/UserListItem.jsx index 672e381c47..731d0eac2b 100644 --- a/awx/ui_next/src/screens/User/UserList/UserListItem.jsx +++ b/awx/ui_next/src/screens/User/UserList/UserListItem.jsx @@ -43,7 +43,7 @@ function UserListItem({ }} /> - + {user.username} {ldapUser && (