From dc45ae420854e8af9cb9bcea6a48d81b0f98b4ed Mon Sep 17 00:00:00 2001 From: MariaAga Date: Tue, 13 Jul 2021 12:07:27 +0200 Subject: [PATCH] Refs #31492 - add WizardTitle --- webpack/JobWizard/JobWizard.js | 13 +++-- webpack/JobWizard/JobWizardConstants.js | 8 ++++ .../JobWizard/__tests__/integration.test.js | 10 ++-- .../steps/AdvancedFields/AdvancedFields.js | 12 +++-- .../__tests__/AdvancedFields.test.js | 11 +++-- .../CategoryAndTemplate.js | 8 ++-- .../CategoryAndTemplate.test.js | 5 +- .../steps/HostsAndInputs/TemplateInputs.js | 2 +- .../__tests__/TemplateInputs.test.js | 11 +++-- .../JobWizard/steps/HostsAndInputs/index.js | 8 ++-- webpack/JobWizard/steps/Schedule/index.js | 47 ++++++++++--------- webpack/JobWizard/steps/form/WizardTitle.js | 14 ++++++ 12 files changed, 89 insertions(+), 60 deletions(-) create mode 100644 webpack/JobWizard/steps/form/WizardTitle.js diff --git a/webpack/JobWizard/JobWizard.js b/webpack/JobWizard/JobWizard.js index 8bebfa451..105413131 100644 --- a/webpack/JobWizard/JobWizard.js +++ b/webpack/JobWizard/JobWizard.js @@ -2,11 +2,10 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Wizard } from '@patternfly/react-core'; import { get } from 'foremanReact/redux/API'; -import { translate as __ } from 'foremanReact/common/I18n'; import history from 'foremanReact/history'; import CategoryAndTemplate from './steps/CategoryAndTemplate/'; import { AdvancedFields } from './steps/AdvancedFields/AdvancedFields'; -import { JOB_TEMPLATE } from './JobWizardConstants'; +import { JOB_TEMPLATE, WIZARD_TITLES } from './JobWizardConstants'; import { selectTemplateError } from './JobWizardSelectors'; import Schedule from './steps/Schedule/'; import HostsAndInputs from './steps/HostsAndInputs/'; @@ -61,7 +60,7 @@ export const JobWizard = () => { const isTemplate = !templateError && !!jobTemplateID; const steps = [ { - name: __('Category and Template'), + name: WIZARD_TITLES.categoryAndTemplate, component: ( { ), }, { - name: __('Target hosts and inputs'), + name: WIZARD_TITLES.hostsAndInputs, component: ( { canJumpTo: isTemplate, }, { - name: __('Advanced Fields'), + name: WIZARD_TITLES.advanced, component: ( { canJumpTo: isTemplate, }, { - name: __('Schedule'), + name: WIZARD_TITLES.schedule, component: , canJumpTo: isTemplate, }, { - name: __('Review Details'), + name: WIZARD_TITLES.review, component:

Review Details

, nextButtonText: 'Run', canJumpTo: isTemplate, diff --git a/webpack/JobWizard/JobWizardConstants.js b/webpack/JobWizard/JobWizardConstants.js index 83b4b16de..0ddf20105 100644 --- a/webpack/JobWizard/JobWizardConstants.js +++ b/webpack/JobWizard/JobWizardConstants.js @@ -14,3 +14,11 @@ export const repeatTypes = { daily: __('Daily'), hourly: __('Hourly'), }; + +export const WIZARD_TITLES = { + categoryAndTemplate: __('Category and Template'), + hostsAndInputs: __('Target hosts and inputs'), + advanced: __('Advanced Fields'), + schedule: __('Schedule'), + review: __('Review Details'), +}; diff --git a/webpack/JobWizard/__tests__/integration.test.js b/webpack/JobWizard/__tests__/integration.test.js index c1598f88c..93b3916ef 100644 --- a/webpack/JobWizard/__tests__/integration.test.js +++ b/webpack/JobWizard/__tests__/integration.test.js @@ -5,6 +5,7 @@ import { render, fireEvent, screen, act } from '@testing-library/react'; import * as api from 'foremanReact/redux/API'; import { JobWizard } from '../JobWizard'; import * as selectors from '../JobWizardSelectors'; +import { WIZARD_TITLES } from '../JobWizardConstants'; import { testSetup, mockApi, @@ -62,13 +63,8 @@ describe('Job wizard fill', () => { ); - const steps = [ - 'Target hosts and inputs', - 'Advanced Fields', - 'Schedule', - 'Review Details', - 'Category and Template', - ]; + const titles = Object.values(WIZARD_TITLES); + const steps = [titles[1], titles[0], ...titles.slice(2)]; // the first title is selected at the beggining // eslint-disable-next-line no-unused-vars for await (const step of steps) { const stepSelector = screen.getByText(step); diff --git a/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js b/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js index 4eee8e4bb..c6a9ac201 100644 --- a/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +++ b/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js @@ -1,8 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; -import { Title, Form } from '@patternfly/react-core'; -import { translate as __ } from 'foremanReact/common/I18n'; +import { Form } from '@patternfly/react-core'; import { selectEffectiveUser, selectAdvancedTemplateInputs, @@ -17,15 +16,18 @@ import { TimeSpanLevelField, TemplateInputsFields, } from './Fields'; +import { WIZARD_TITLES } from '../../JobWizardConstants'; +import { WizardTitle } from '../form/WizardTitle'; export const AdvancedFields = ({ advancedValues, setAdvancedValues }) => { const effectiveUser = useSelector(selectEffectiveUser); const templateInputs = useSelector(selectAdvancedTemplateInputs); return ( <> - - {__('Advanced Fields')} - +
{ ); await act(async () => { - fireEvent.click(screen.getByText('Advanced Fields')); + fireEvent.click(screen.getByText(WIZARD_TITLES.advanced)); }); const searchValue = 'search test'; const textValue = 'I am a text'; @@ -99,7 +100,7 @@ describe('AdvancedFields', () => { fireEvent.click(selectField); await act(async () => { await fireEvent.click(screen.getByText('option 2')); - fireEvent.click(screen.getAllByText('Advanced Fields')[0]); // to remove focus + fireEvent.click(screen.getAllByText(WIZARD_TITLES.advanced)[0]); // to remove focus await fireEvent.change(textField, { target: { value: textValue }, }); @@ -119,9 +120,11 @@ describe('AdvancedFields', () => { expect(searchField.value).toBe(searchValue); expect(dateField.value).toBe(dateValue); await act(async () => { - fireEvent.click(screen.getByText('Category and Template')); + fireEvent.click(screen.getByText(WIZARD_TITLES.categoryAndTemplate)); }); - expect(screen.getAllByText('Category and Template')).toHaveLength(3); + expect(screen.getAllByText(WIZARD_TITLES.categoryAndTemplate)).toHaveLength( + 3 + ); await act(async () => { fireEvent.click(screen.getByText('Advanced Fields')); diff --git a/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js b/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js index fe7642ecb..5394d1f5a 100644 --- a/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +++ b/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js @@ -1,9 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Title, Text, TextVariants, Form, Alert } from '@patternfly/react-core'; +import { Text, TextVariants, Form, Alert } from '@patternfly/react-core'; import { translate as __ } from 'foremanReact/common/I18n'; import { SelectField } from '../form/SelectField'; import { GroupedSelectField } from '../form/GroupedSelectField'; +import { WizardTitle } from '../form/WizardTitle'; +import { WIZARD_TITLES } from '../../JobWizardConstants'; export const CategoryAndTemplate = ({ jobCategories, @@ -40,9 +42,7 @@ export const CategoryAndTemplate = ({ const isError = !!(categoryError || allTemplatesError || templateError); return ( <> - - {__('Category and Template')} - + {__('All fields are required.')} { await act(async () => { await fireEvent.click(screen.getByText('Puppet')); }); - fireEvent.click(screen.getAllByText('Category and Template')[0]); // to remove focus + fireEvent.click(screen.getAllByText(WIZARD_TITLES.categoryAndTemplate)[0]); // to remove focus expect( screen.queryAllByLabelText('Ansible Commands', { selector: 'button' }) ).toHaveLength(0); @@ -47,7 +48,7 @@ describe('Category And Template', () => { await act(async () => { await fireEvent.click(screen.getByText('template2')); }); - fireEvent.click(screen.getAllByText('Category and Template')[0]); // to remove focus + fireEvent.click(screen.getAllByText(WIZARD_TITLES.categoryAndTemplate)[0]); // to remove focus expect( screen.queryAllByDisplayValue('template1', { selector: 'button' }) ).toHaveLength(0); diff --git a/webpack/JobWizard/steps/HostsAndInputs/TemplateInputs.js b/webpack/JobWizard/steps/HostsAndInputs/TemplateInputs.js index 5d4518aef..c0b84a3aa 100644 --- a/webpack/JobWizard/steps/HostsAndInputs/TemplateInputs.js +++ b/webpack/JobWizard/steps/HostsAndInputs/TemplateInputs.js @@ -5,7 +5,7 @@ import { formatter } from '../form/Formatter'; export const TemplateInputs = ({ inputs, value, setValue }) => { if (inputs.length) - return <>{inputs?.map(input => formatter(input, value, setValue))}; + return inputs.map(input => formatter(input, value, setValue)); return (

{__('There are no available input fields for the selected template.')} diff --git a/webpack/JobWizard/steps/HostsAndInputs/__tests__/TemplateInputs.test.js b/webpack/JobWizard/steps/HostsAndInputs/__tests__/TemplateInputs.test.js index 071baece2..d58dc85f5 100644 --- a/webpack/JobWizard/steps/HostsAndInputs/__tests__/TemplateInputs.test.js +++ b/webpack/JobWizard/steps/HostsAndInputs/__tests__/TemplateInputs.test.js @@ -5,6 +5,7 @@ import * as api from 'foremanReact/redux/API'; import { JobWizard } from '../../../JobWizard'; import * as selectors from '../../../JobWizardSelectors'; import { testSetup, mockApi } from '../../../__tests__/fixtures'; +import { WIZARD_TITLES } from '../../../JobWizardConstants'; const store = testSetup(selectors, api); mockApi(api); @@ -17,7 +18,7 @@ describe('TemplateInputs', () => { ); await act(async () => { - fireEvent.click(screen.getByText('Target hosts and inputs')); + fireEvent.click(screen.getByText(WIZARD_TITLES.hostsAndInputs)); }); const textValue = 'I am a plain text'; const textField = screen.getByLabelText('plain hidden', { @@ -35,12 +36,14 @@ describe('TemplateInputs', () => { }).value ).toBe(textValue); await act(async () => { - fireEvent.click(screen.getByText('Category and Template')); + fireEvent.click(screen.getByText(WIZARD_TITLES.categoryAndTemplate)); }); - expect(screen.getAllByText('Category and Template')).toHaveLength(3); + expect(screen.getAllByText(WIZARD_TITLES.categoryAndTemplate)).toHaveLength( + 3 + ); await act(async () => { - fireEvent.click(screen.getByText('Target hosts and inputs')); + fireEvent.click(screen.getByText(WIZARD_TITLES.hostsAndInputs)); }); expect(textField.value).toBe(textValue); }); diff --git a/webpack/JobWizard/steps/HostsAndInputs/index.js b/webpack/JobWizard/steps/HostsAndInputs/index.js index ad49b5902..a33a84f91 100644 --- a/webpack/JobWizard/steps/HostsAndInputs/index.js +++ b/webpack/JobWizard/steps/HostsAndInputs/index.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Title, Button, Form, FormGroup } from '@patternfly/react-core'; +import { Button, Form, FormGroup } from '@patternfly/react-core'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; import { translate as __ } from 'foremanReact/common/I18n'; @@ -7,6 +7,8 @@ import { selectTemplateInputs } from '../../JobWizardSelectors'; import { SelectField } from '../form/SelectField'; import { SelectedChips } from './SelectedChips'; import { TemplateInputs } from './TemplateInputs'; +import { WIZARD_TITLES } from '../../JobWizardConstants'; +import { WizardTitle } from '../form/WizardTitle'; const HostsAndInputs = ({ templateValues, @@ -24,9 +26,7 @@ const HostsAndInputs = ({ const [hostMethod, setHostMethod] = useState(hostMethods[0]); return ( <> - - {__('Target hosts and inputs')} - + { const [repeatType, setRepeatType] = useState(repeatTypes.noRepeat); @@ -14,27 +15,29 @@ const Schedule = () => { const [ends, setEnds] = useState(''); return ( - - {__('Schedule')} - + <> + + + - - - - - + + + + + + ); }; diff --git a/webpack/JobWizard/steps/form/WizardTitle.js b/webpack/JobWizard/steps/form/WizardTitle.js new file mode 100644 index 000000000..1c4fb2a42 --- /dev/null +++ b/webpack/JobWizard/steps/form/WizardTitle.js @@ -0,0 +1,14 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Title } from '@patternfly/react-core'; + +export const WizardTitle = ({ title, ...props }) => ( + + {title} + +); + +WizardTitle.propTypes = { + title: PropTypes.string.isRequired, +}; +export default WizardTitle;