after running pf code mod tool to auto update files to conform to v4 and a few manual tweaks

This commit is contained in:
John Mitchell 2020-06-10 11:20:07 -04:00
parent 475b733890
commit e49a99e0f6
59 changed files with 339 additions and 106 deletions

View File

@ -67,9 +67,9 @@ export default function AlertModal({
return (
<Modal
header={customHeader}
isFooterLeftAligned
isOpen={Boolean(isOpen)}
isSmall
variant="small"
title={title}
{...props}
>

View File

@ -43,7 +43,7 @@ class AnsibleSelect extends React.Component {
onChange={this.onSelectChange}
onBlur={onBlur}
aria-label={i18n._(t`Select Input`)}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
className={className}
isDisabled={isDisabled}
>

View File

@ -74,8 +74,8 @@ function AssociateModal({
return (
<Fragment>
<Modal
isFooterLeftAligned
isLarge
variant="large"
title={title}
isOpen={isModalOpen}
onClose={handleClose}

View File

@ -39,7 +39,7 @@ function VariablesDetail({ value, label, rows, fullHeight }) {
fullWidth
css="grid-column: 1 / -1"
>
<Split gutter="sm">
<Split hasGutter>
<SplitItem>
<div className="pf-c-form__label">
<span

View File

@ -35,7 +35,7 @@ function VariablesField({
return (
<div className="pf-c-form__group">
<FieldHeader>
<Split gutter="sm">
<Split hasGutter>
<SplitItem>
<label htmlFor={id} className="pf-c-form__label">
<span className="pf-c-form__label-text">{label}</span>

View File

@ -35,7 +35,7 @@ function VariablesInput(props) {
return (
<div className={`pf-c-form__group ${className || ''}`}>
<Split gutter="sm">
<Split hasGutter>
<SplitItem>
<label htmlFor={id} className="pf-c-form__label">
{label}

View File

@ -67,7 +67,7 @@ class DataListToolbar extends React.Component {
</ToolbarItem>
</ToolbarGroup>
)}
<ToolbarToggleGroup toggleIcon={<SearchIcon />} breakpoint="lg">
<ToolbarToggleGroup toggleIcon={<SearchIcon />} show={{ lg: 'show' }}>
<ToolbarItem>
<Search
qsConfig={qsConfig}

View File

@ -29,14 +29,14 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={label}
>
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
<TextArea
id={id}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
resizeOrientation="vertical"
{...rest}
{...field}
@ -51,14 +51,14 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={label}
>
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
<TextInput
id={id}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
{...rest}
{...field}
type={type}

View File

@ -14,7 +14,7 @@ function PasswordField(props) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={label}
>
<InputGroup>

View File

@ -44,7 +44,7 @@ function PasswordInput(props) {
value={field.value === '$encrypted$' ? '' : field.value}
isDisabled={isDisabled}
isRequired={isRequired}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
type={inputType}
onChange={(_, event) => {
field.onChange(event);

View File

@ -27,7 +27,7 @@ const InventoryLookupField = withI18n()(({ i18n, host }) => {
label={i18n._(t`Inventory`)}
isRequired
fieldId="inventory-lookup"
isValid={!inventoryMeta.touched || !inventoryMeta.error}
validated={(!inventoryMeta.touched || !inventoryMeta.error) ? 'default' : 'error'}
helperTextInvalid={inventoryMeta.error}
>
<FieldTooltip

View File

@ -101,7 +101,7 @@ function JobTypeField({ i18n }) {
<FormGroup
fieldId="propmt-job-type"
label={i18n._(t`Job Type`)}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
>
<FieldTooltip
content={i18n._(t`For job templates, select run to execute the playbook.
@ -132,7 +132,7 @@ function VerbosityField({ i18n }) {
return (
<FormGroup
fieldId="prompt-verbosity"
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={i18n._(t`Verbosity`)}
>
<FieldTooltip

View File

@ -96,7 +96,7 @@ function MultipleChoiceField({ question }) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={question.required}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={question.question_name}
>
<FieldTooltip content={question.question_description} />
@ -124,7 +124,7 @@ function MultiSelectField({ question }) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={question.required}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={question.question_name}
>
<FieldTooltip content={question.question_description} />
@ -139,7 +139,7 @@ function MultiSelectField({ question }) {
helpers.setValue(field.value.concat(option));
}
}}
isExpanded={isOpen}
isOpen={isOpen}
selections={field.value}
>
{question.choices.split('\n').map(opt => (

View File

@ -84,7 +84,7 @@ function CredentialLookup({
<FormGroup
fieldId="credential"
isRequired={required}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={label}
helperTextInvalid={helperTextInvalid}
>

View File

@ -142,8 +142,8 @@ function Lookup(props) {
</ChipHolder>
</InputGroup>
<Modal
isFooterLeftAligned
isLarge
variant="large"
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)}
isOpen={isModalOpen}
onClose={closeModal}
@ -199,7 +199,7 @@ Lookup.defaultProps = {
<Chip
key={item.id}
onClick={() => removeItem(item)}
isReadOnly={!canDelete}
>
{item.name}
</Chip>

View File

@ -49,7 +49,7 @@ function OrganizationLookup({
fieldId="organization"
helperTextInvalid={helperTextInvalid}
isRequired={required}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={i18n._(t`Organization`)}
>
<Lookup

View File

@ -63,7 +63,7 @@ function ProjectLookup({
fieldId="project"
helperTextInvalid={helperTextInvalid}
isRequired={required}
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={i18n._(t`Project`)}
>
{tooltip && <FieldTooltip content={tooltip} />}

View File

@ -50,8 +50,8 @@ function TagMultiSelect({ onChange, value }) {
return name;
}}
selections={selections}
isExpanded={isExpanded}
ariaLabelledBy="tag-select"
isOpen={isExpanded}
aria-labelledby="tag-select"
>
{renderOptions(options)}
</Select>

View File

@ -194,7 +194,7 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
totalChips={overrides.job_tags.split(',').length}
>
{overrides.job_tags.split(',').map(jobTag => (
<Chip key={jobTag} isReadOnly>
<Chip key={jobTag} >
{jobTag}
</Chip>
))}
@ -212,7 +212,7 @@ function PromptDetail({ i18n, resource, launchConfig = {}, overrides = {} }) {
totalChips={overrides.skip_tags.split(',').length}
>
{overrides.skip_tags.split(',').map(skipTag => (
<Chip key={skipTag} isReadOnly>
<Chip key={skipTag} >
{skipTag}
</Chip>
))}

View File

@ -126,7 +126,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
totalChips={source_regions.split(',').length}
>
{source_regions.split(',').map(region => (
<Chip key={region} isReadOnly>
<Chip key={region} >
{region}
</Chip>
))}
@ -144,7 +144,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
totalChips={instance_filters.split(',').length}
>
{instance_filters.split(',').map(filter => (
<Chip key={filter} isReadOnly>
<Chip key={filter} >
{filter}
</Chip>
))}
@ -159,7 +159,7 @@ function PromptInventorySourceDetail({ i18n, resource }) {
value={
<ChipGroup numChips={5} totalChips={group_by.split(',').length}>
{group_by.split(',').map(group => (
<Chip key={group} isReadOnly>
<Chip key={group} >
{group}
</Chip>
))}

View File

@ -196,7 +196,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
totalChips={summary_fields.labels.results.length}
>
{summary_fields.labels.results.map(label => (
<Chip key={label.id} isReadOnly>
<Chip key={label.id} >
{label.name}
</Chip>
))}
@ -211,7 +211,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
value={
<ChipGroup numChips={5} totalChips={instance_groups.length}>
{instance_groups.map(ig => (
<Chip key={ig.id} isReadOnly>
<Chip key={ig.id} >
{ig.name}
</Chip>
))}
@ -226,7 +226,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
value={
<ChipGroup numChips={5} totalChips={job_tags.split(',').length}>
{job_tags.split(',').map(jobTag => (
<Chip key={jobTag} isReadOnly>
<Chip key={jobTag} >
{jobTag}
</Chip>
))}
@ -241,7 +241,7 @@ function PromptJobTemplateDetail({ i18n, resource }) {
value={
<ChipGroup numChips={5} totalChips={skip_tags.split(',').length}>
{skip_tags.split(',').map(skipTag => (
<Chip key={skipTag} isReadOnly>
<Chip key={skipTag} >
{skipTag}
</Chip>
))}

View File

@ -114,7 +114,7 @@ function PromptWFJobTemplateDetail({ i18n, resource }) {
totalChips={summary_fields.labels.results.length}
>
{summary_fields.labels.results.map(label => (
<Chip key={label.id} isReadOnly>
<Chip key={label.id} >
{label.name}
</Chip>
))}

View File

@ -59,7 +59,7 @@ class ResourceAccessListItem extends React.Component {
return (
<Chip
key={role.id}
isReadOnly={!role.user_capabilities.unattach}
onClick={() => {
onRoleDelete(role, accessRecord);
}}

View File

@ -1,6 +1,6 @@
import React from 'react';
import { shape, string, number, arrayOf, node, oneOfType } from 'prop-types';
import { Tab, Tabs } from '@patternfly/react-core';
import { Tab, Tabs, TabTitleText } from '@patternfly/react-core';
import { useHistory } from 'react-router-dom';
function RoutedTabs(props) {
@ -36,7 +36,7 @@ function RoutedTabs(props) {
eventKey={tab.id}
key={tab.id}
link={tab.link}
title={tab.name}
title={<TabTitleText>{tab.name}</TabTitleText>}
/>
))}
</Tabs>

View File

@ -194,7 +194,7 @@ function ScheduleDetail({ schedule, i18n }) {
totalChips={job_tags.split(',').length}
>
{job_tags.split(',').map(jobTag => (
<Chip key={jobTag} isReadOnly>
<Chip key={jobTag} >
{jobTag}
</Chip>
))}
@ -212,7 +212,7 @@ function ScheduleDetail({ schedule, i18n }) {
totalChips={skip_tags.split(',').length}
>
{skip_tags.split(',').map(skipTag => (
<Chip key={skipTag} isReadOnly>
<Chip key={skipTag} >
{skipTag}
</Chip>
))}

View File

@ -36,7 +36,7 @@ function ScheduleOccurrences({ preview = { local: [], utc: [] }, i18n }) {
fullWidth
css="grid-column: 1 / -1"
>
<Split gutter="sm">
<Split hasGutter>
<SplitItem>
<OccurrencesLabel>
<span>{i18n._(t`Occurrences`)}</span>

View File

@ -231,7 +231,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-run-every"
helperTextInvalid={intervalMeta.error}
isRequired
isValid={!intervalMeta.touched || !intervalMeta.error}
validated={(!intervalMeta.touched || !intervalMeta.error) ? 'default' : 'error'}
label={i18n._(t`Run every`)}
>
<div css="display: flex">
@ -255,7 +255,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-days-of-week"
helperTextInvalid={daysOfWeekMeta.error}
isRequired
isValid={!daysOfWeekMeta.touched || !daysOfWeekMeta.error}
validated={(!daysOfWeekMeta.touched || !daysOfWeekMeta.error) ? 'default' : 'error'}
label={i18n._(t`On days`)}
>
<div css="display: flex">
@ -339,7 +339,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-run-on"
helperTextInvalid={runOnMeta.error}
isRequired
isValid={!runOnMeta.touched || !runOnMeta.error}
validated={(!runOnMeta.touched || !runOnMeta.error) ? 'default' : 'error'}
label={i18n._(t`Run on`)}
>
<RunOnRadio
@ -502,7 +502,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-end"
helperTextInvalid={endMeta.error}
isRequired
isValid={!endMeta.touched || !endMeta.error}
validated={(!endMeta.touched || !endMeta.error) ? 'default' : 'error'}
label={i18n._(t`End`)}
>
<Radio
@ -556,7 +556,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-end-datetime"
helperTextInvalid={endDateTimeMeta.error}
isRequired
isValid={!endDateTimeMeta.touched || !endDateTimeMeta.error}
validated={(!endDateTimeMeta.touched || !endDateTimeMeta.error) ? 'default' : 'error'}
label={i18n._(t`End date/time`)}
>
<input

View File

@ -104,7 +104,7 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-start-datetime"
helperTextInvalid={startDateTimeMeta.error}
isRequired
isValid={!startDateTimeMeta.touched || !startDateTimeMeta.error}
validated={(!startDateTimeMeta.touched || !startDateTimeMeta.error) ? 'default' : 'error'}
label={i18n._(t`Start date/time`)}
>
<input
@ -120,7 +120,7 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-timezone"
helperTextInvalid={timezoneMeta.error}
isRequired
isValid={!timezoneMeta.touched || !timezoneMeta.error}
validated={(!timezoneMeta.touched || !timezoneMeta.error) ? 'default' : 'error'}
label={i18n._(t`Local time zone`)}
>
<AnsibleSelect
@ -134,7 +134,7 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-requency"
helperTextInvalid={frequencyMeta.error}
isRequired
isValid={!frequencyMeta.touched || !frequencyMeta.error}
validated={(!frequencyMeta.touched || !frequencyMeta.error) ? 'default' : 'error'}
label={i18n._(t`Run frequency`)}
>
<AnsibleSelect

View File

@ -251,7 +251,7 @@ class Search extends React.Component {
const [, ...value] = chip.key.split(':');
return value.join(':');
})}
isExpanded={isFilterDropdownOpen}
isOpen={isFilterDropdownOpen}
placeholderText={`Filter By ${name}`}
>
{options.map(([optionKey, optionLabel]) => (
@ -270,7 +270,7 @@ class Search extends React.Component {
this.handleFilterBooleanSelect(key, selection)
}
selections={chipsByKey[key].chips[0]}
isExpanded={isFilterDropdownOpen}
isOpen={isFilterDropdownOpen}
placeholderText={`Filter By ${name}`}
>
<SelectOption key="true" value="true">

View File

@ -30,7 +30,7 @@ class SelectedList extends Component {
const renderChip =
renderItemChip ||
(({ item, removeItem }) => (
<Chip key={item.id} onClick={removeItem} isReadOnly={isReadOnly}>
<Chip key={item.id} onClick={removeItem} >
{item[displayKey]}
</Chip>
));

View File

@ -104,7 +104,7 @@ function CredentialFormFields({
fieldId="credential-credentialType"
helperTextInvalid={credTypeMeta.error}
isRequired
isValid={!credTypeMeta.touched || !credTypeMeta.error}
validated={(!credTypeMeta.touched || !credTypeMeta.error) ? 'default' : 'error'}
label={i18n._(t`Credential Type`)}
>
<AnsibleSelect

View File

@ -0,0 +1,103 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import {
Button,
ButtonVariant,
FormGroup,
InputGroup,
Tooltip,
} from '@patternfly/react-core';
import { KeyIcon } from '@patternfly/react-icons';
import { CredentialPluginPrompt } from './CredentialPluginPrompt';
import CredentialPluginSelected from './CredentialPluginSelected';
function CredentialPluginField(props) {
const {
children,
id,
name,
label,
validate,
isRequired,
isDisabled,
i18n,
} = props;
const [showPluginWizard, setShowPluginWizard] = useState(false);
const [field, meta, helpers] = useField({ name, validate });
const isValid = !(meta.touched && meta.error);
return (
<FormGroup
fieldId={id}
helperTextInvalid={meta.error}
isRequired={isRequired}
validated={(isValid) ? 'default' : 'error'}
label={label}
>
{field?.value?.credential ? (
<CredentialPluginSelected
credential={field?.value?.credential}
onClearPlugin={() => helpers.setValue('')}
onEditPlugin={() => setShowPluginWizard(true)}
/>
) : (
<InputGroup>
{React.cloneElement(children, {
...field,
isRequired,
onChange: (_, event) => {
field.onChange(event);
},
})}
<Tooltip
content={i18n._(
t`Populate field from an external secret management system`
)}
>
<Button
variant={ButtonVariant.control}
aria-label={i18n._(
t`Populate field from an external secret management system`
)}
onClick={() => setShowPluginWizard(true)}
isDisabled={isDisabled}
>
<KeyIcon />
</Button>
</Tooltip>
</InputGroup>
)}
{showPluginWizard && (
<CredentialPluginPrompt
initialValues={typeof field.value === 'object' ? field.value : {}}
onClose={() => setShowPluginWizard(false)}
onSubmit={val => {
val.touched = true;
helpers.setValue(val);
setShowPluginWizard(false);
}}
/>
)}
</FormGroup>
);
}
CredentialPluginField.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
validate: PropTypes.func,
isRequired: PropTypes.bool,
isDisabled: PropTypes.bool,
};
CredentialPluginField.defaultProps = {
validate: () => {},
isRequired: false,
isDisabled: false,
};
export default withI18n()(CredentialPluginField);

View File

@ -0,0 +1,136 @@
import React, { useState } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import {
FileUpload,
FormGroup,
TextArea,
TextInput,
} from '@patternfly/react-core';
import {
FormColumnLayout,
FormFullWidthLayout,
} from '../../../../components/FormLayout';
import { required } from '../../../../util/validators';
import { CredentialPluginField } from '../CredentialPlugins';
const GoogleComputeEngineSubForm = ({ i18n }) => {
const [fileError, setFileError] = useState(null);
const [filename, setFilename] = useState('');
const [file, setFile] = useState('');
const inputsUsernameHelpers = useField({
name: 'inputs.username',
})[2];
const inputsProjectHelpers = useField({
name: 'inputs.project',
})[2];
const inputsSSHKeyDataHelpers = useField({
name: 'inputs.ssh_key_data',
})[2];
return (
<FormColumnLayout>
<FormGroup
fieldId="credential-gce-file"
validated={(!fileError) ? 'default' : 'error'}
label={i18n._(t`Service account JSON file`)}
helperText={i18n._(
t`Select a JSON formatted service account key to autopopulate the following fields.`
)}
helperTextInvalid={fileError}
>
<FileUpload
id="credential-gce-file"
value={file}
filename={filename}
filenamePlaceholder={i18n._(t`Choose a .json file`)}
onChange={async value => {
if (value) {
try {
setFile(value);
setFilename(value.name);
const fileText = await value.text();
const fileJSON = JSON.parse(fileText);
if (
!fileJSON.client_email &&
!fileJSON.project_id &&
!fileJSON.private_key
) {
setFileError(
i18n._(
t`Expected at least one of client_email, project_id or private_key to be present in the file.`
)
);
} else {
inputsUsernameHelpers.setValue(fileJSON.client_email || '');
inputsProjectHelpers.setValue(fileJSON.project_id || '');
inputsSSHKeyDataHelpers.setValue(fileJSON.private_key || '');
setFileError(null);
}
} catch {
setFileError(
i18n._(
t`There was an error parsing the file. Please check the file formatting and try again.`
)
);
}
} else {
setFile('');
setFilename('');
inputsUsernameHelpers.setValue('');
inputsProjectHelpers.setValue('');
inputsSSHKeyDataHelpers.setValue('');
setFileError(null);
}
}}
dropzoneProps={{
accept: '.json',
onDropRejected: () => {
setFileError(
i18n._(
t`File upload rejected. Please select a single .json file.`
)
);
},
}}
/>
</FormGroup>
<CredentialPluginField
id="credential-username"
label={i18n._(t`Service account email address`)}
name="inputs.username"
type="email"
validate={required(null, i18n)}
isRequired
>
<TextInput id="credential-username" />
</CredentialPluginField>
<CredentialPluginField
id="credential-project"
label={i18n._(t`Project`)}
name="inputs.project"
>
<TextInput id="credential-project" />
</CredentialPluginField>
<FormFullWidthLayout>
<CredentialPluginField
id="credential-sshKeyData"
label={i18n._(t`RSA private key`)}
name="inputs.ssh_key_data"
type="textarea"
validate={required(null, i18n)}
isRequired
>
<TextArea
id="credential-sshKeyData"
rows={6}
resizeOrientation="vertical"
/>
</CredentialPluginField>
</FormFullWidthLayout>
</FormColumnLayout>
);
};
export default withI18n()(GoogleComputeEngineSubForm);

View File

@ -81,7 +81,7 @@ function InventoryDetail({ inventory, i18n }) {
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
{instanceGroups.map(ig => (
<Chip key={ig.id} isReadOnly>
<Chip key={ig.id} >
{ig.name}
</Chip>
))}

View File

@ -248,7 +248,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
totalChips={source_regions.split(',').length}
>
{source_regions.split(',').map(region => (
<Chip key={region} isReadOnly>
<Chip key={region} >
{region}
</Chip>
))}
@ -266,7 +266,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
totalChips={instance_filters.split(',').length}
>
{instance_filters.split(',').map(filter => (
<Chip key={filter} isReadOnly>
<Chip key={filter} >
{filter}
</Chip>
))}
@ -281,7 +281,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
value={
<ChipGroup numChips={5} totalChips={group_by.split(',').length}>
{group_by.split(',').map(group => (
<Chip key={group} isReadOnly>
<Chip key={group} >
{group}
</Chip>
))}

View File

@ -117,7 +117,7 @@ const InventorySourceFormFields = ({ sourceOptions, i18n }) => {
fieldId="source"
helperTextInvalid={sourceMeta.error}
isRequired
isValid={!sourceMeta.touched || !sourceMeta.error}
validated={(!sourceMeta.touched || !sourceMeta.error) ? 'default' : 'error'}
label={i18n._(t`Source`)}
>
<AnsibleSelect

View File

@ -83,10 +83,8 @@ const SCMSubForm = ({ i18n }) => {
<FormGroup
fieldId="source_path"
helperTextInvalid={sourcePathError?.message || sourcePathMeta.error}
isValid={
(!sourcePathMeta.error || !sourcePathMeta.touched) &&
!sourcePathError?.message
}
validated={((!sourcePathMeta.error || !sourcePathMeta.touched) &&
!sourcePathError?.message) ? 'default' : 'error'}
isRequired
label={i18n._(t`Inventory file`)}
>

View File

@ -229,7 +229,7 @@ export const VerbosityField = withI18n()(({ i18n }) => {
return (
<FormGroup
fieldId="verbosity"
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={i18n._(t`Verbosity`)}
>
<FieldTooltip

View File

@ -232,7 +232,7 @@ function JobDetail({ job, i18n }) {
value={
<ChipGroup numChips={5} totalChips={labels.results.length}>
{labels.results.map(l => (
<Chip key={l.id} isReadOnly>
<Chip key={l.id} >
{l.name}
</Chip>
))}

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Modal as PFModal, Tab, Tabs as PFTabs } from '@patternfly/react-core';
import { Modal as PFModal, Tab, Tabs as PFTabs, TabTitleText } from '@patternfly/react-core';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@ -147,7 +147,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
<Tab
aria-label={i18n._(t`Details tab`)}
eventKey={0}
title={i18n._(t`Details`)}
title={<TabTitleText>{i18n._(t`Details`)}</TabTitleText>}
>
<DetailList style={{ alignItems: 'center' }} gutter="sm">
<Detail
@ -175,7 +175,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={1}
title={i18n._(t`JSON`)}
title={<TabTitleText>{i18n._(t`JSON`)}</TabTitleText>}
aria-label={i18n._(t`JSON tab`)}
>
{activeTabKey === 1 && jsonObj ? (
@ -193,7 +193,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={2}
title={i18n._(t`Standard Out`)}
title={<TabTitleText>{i18n._(t`Standard Out`)}</TabTitleText>}
aria-label={i18n._(t`Standard out tab`)}
>
{activeTabKey === 2 && stdOut ? (
@ -211,7 +211,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={3}
title={i18n._(t`Standard Error`)}
title={<TabTitleText>{i18n._(t`Standard Error`)}</TabTitleText>}
aria-label={i18n._(t`Standard error tab`)}
>
{activeTabKey === 3 && stdErr ? (

View File

@ -105,7 +105,7 @@ function OrganizationDetail({ i18n, organization }) {
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
{instanceGroups.map(ig => (
<Chip key={ig.id} isReadOnly>
<Chip key={ig.id} >
{ig.name}
</Chip>
))}

View File

@ -172,7 +172,7 @@ function ProjectFormFields({
fieldId="project-scm-type"
helperTextInvalid={scmTypeMeta.error}
isRequired
isValid={!scmTypeMeta.touched || !scmTypeMeta.error}
validated={(!scmTypeMeta.touched || !scmTypeMeta.error) ? 'default' : 'error'}
label={i18n._(t`Source Control Credential Type`)}
>
<AnsibleSelect

View File

@ -81,7 +81,7 @@ const ManualSubForm = ({
fieldId="project-local-path"
helperTextInvalid={pathMeta.error}
isRequired
isValid={!pathMeta.touched || !pathMeta.error}
validated={(!pathMeta.touched || !pathMeta.error) ? 'default' : 'error'}
label={i18n._(t`Playbook Directory`)}
>
<FieldTooltip

View File

@ -40,9 +40,7 @@ function TeamAccessListItem({ role, i18n, detailUrl, onSelect }) {
label={i18n._(t`Role`)}
value={
<Chip
isReadOnly={
!role.summary_fields.user_capabilities.unattach
}
key={role.name}
aria-label={role.name}
onClick={() => onSelect(role)}

View File

@ -304,7 +304,7 @@ function JobTemplateDetail({ i18n, template }) {
totalChips={summary_fields.labels.results.length}
>
{summary_fields.labels.results.map(l => (
<Chip key={l.id} isReadOnly>
<Chip key={l.id} >
{l.name}
</Chip>
))}
@ -319,7 +319,7 @@ function JobTemplateDetail({ i18n, template }) {
value={
<ChipGroup numChips={5} totalChips={instanceGroups.length}>
{instanceGroups.map(ig => (
<Chip key={ig.id} isReadOnly>
<Chip key={ig.id} >
{ig.name}
</Chip>
))}
@ -334,7 +334,7 @@ function JobTemplateDetail({ i18n, template }) {
value={
<ChipGroup numChips={5} totalChips={job_tags.split(',').length}>
{job_tags.split(',').map(jobTag => (
<Chip key={jobTag} isReadOnly>
<Chip key={jobTag} >
{jobTag}
</Chip>
))}
@ -349,7 +349,7 @@ function JobTemplateDetail({ i18n, template }) {
value={
<ChipGroup numChips={5} totalChips={skip_tags.split(',').length}>
{skip_tags.split(',').map(skipTag => (
<Chip key={skipTag} isReadOnly>
<Chip key={skipTag} >
{skipTag}
</Chip>
))}

View File

@ -125,7 +125,7 @@ function SurveyListItem({
totalChips={question.default.split('\n').length}
>
{question.default.split('\n').map(chip => (
<Chip key={chip} isReadOnly>
<Chip key={chip} >
{chip}
</Chip>
))}

View File

@ -32,7 +32,7 @@ function SurveyPreviewModal({
title={i18n._(t`Survey Preview`)}
isOpen={isPreviewModalOpen}
onClose={() => onToggleModalOpen(false)}
isSmall
variant="small"
>
<Formik initialValues={initialValues}>
{() => (
@ -97,7 +97,7 @@ function SurveyPreviewModal({
isDisabled
isReadOnly
variant={SelectVariant.typeaheadMulti}
isExpanded={false}
isOpen={false}
selections={q.default.length > 0 && q.default.split('\n')}
onToggle={() => {}}
aria-label={i18n._(t`Multi-Select`)}

View File

@ -172,7 +172,7 @@ function WorkflowJobTemplateDetail({ template, i18n }) {
totalChips={summary_fields.labels.results.length}
>
{summary_fields.labels.results.map(l => (
<Chip key={l.id} isReadOnly>
<Chip key={l.id} >
{l.name}
</Chip>
))}

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { BaseSizes, Title } from '@patternfly/react-core';
import { Title } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { WorkflowDispatchContext } from '../../../../../contexts/Workflow';
@ -10,7 +10,7 @@ function LinkAddModal({ i18n }) {
return (
<LinkModal
header={
<Title headingLevel="h1" size={BaseSizes['2xl']}>
<Title headingLevel="h1" size="xl">
{i18n._(t`Add Link`)}
</Title>
}

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { BaseSizes, Title } from '@patternfly/react-core';
import { Title } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { WorkflowDispatchContext } from '../../../../../contexts/Workflow';
@ -10,7 +10,7 @@ function LinkEditModal({ i18n }) {
return (
<LinkModal
header={
<Title headingLevel="h1" size={BaseSizes['2xl']}>
<Title headingLevel="h1" size="xl">
{i18n._(t`Edit Link`)}
</Title>
}

View File

@ -20,7 +20,7 @@ function LinkModal({ header, i18n, onConfirm }) {
width={600}
header={header}
isOpen
isFooterLeftAligned
title={i18n._(t`Workflow Link`)}
onClose={() => dispatch({ type: 'CANCEL_LINK_MODAL' })}
actions={[

View File

@ -131,14 +131,14 @@ function NodeTypeStep({
<FormGroup
fieldId="approval-name"
isRequired
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
label={i18n._(t`Name`)}
>
<TextInput
autoFocus
id="approval-name"
isRequired
isValid={isValid}
validated={(isValid) ? 'default' : 'error'}
type="text"
{...field}
onChange={(value, evt) => {

View File

@ -131,9 +131,9 @@ function NodeViewModal({ i18n }) {
return (
<Modal
isLarge
variant="large"
isOpen
isFooterLeftAligned
title={unifiedJobTemplate.name}
onClose={() => dispatch({ type: 'SET_NODE_TO_VIEW', value: null })}
actions={[

View File

@ -11,7 +11,7 @@ function UnsavedChangesModal({ i18n, onSaveAndExit, onExit }) {
<Modal
width={600}
isOpen
isFooterLeftAligned
title={i18n._(t`Warning: Unsaved Changes`)}
onClose={() => dispatch({ type: 'TOGGLE_UNSAVED_CHANGES_MODAL' })}
actions={[

View File

@ -68,7 +68,7 @@ function VisualizerToolbar({
return (
<div id="visualizer-toolbar">
<div css="align-items: center; border-bottom: 1px solid grey; display: flex; height: 56px; padding: 0px 20px;">
<Title size="xl" id="visualizer-toolbar-template-name">
<Title headingLevel="h2" size="xl" id="visualizer-toolbar-template-name">
{template.name}
</Title>
<div css="align-items: center; display: flex; flex: 1; justify-content: flex-end">

View File

@ -291,7 +291,7 @@ function JobTemplateForm({
<FormGroup
fieldId="template-playbook"
helperTextInvalid={playbookMeta.error}
isValid={!playbookMeta.touched || !playbookMeta.error}
validated={(!playbookMeta.touched || !playbookMeta.error) ? 'default' : 'error'}
isRequired
label={i18n._(t`Playbook`)}
>
@ -381,7 +381,7 @@ function JobTemplateForm({
<TextInput
id="template-limit"
{...limitField}
isValid={!limitMeta.touched || !limitMeta.error}
validated={(!limitMeta.touched || !limitMeta.error) ? 'default' : 'error'}
onChange={value => {
limitHelpers.setValue(value);
}}

View File

@ -83,8 +83,8 @@ function LabelSelect({ value, placeholder, onChange, onError, createText }) {
}}
isDisabled={isLoading}
selections={selections}
isExpanded={isExpanded}
ariaLabelledBy="label-select"
isOpen={isExpanded}
aria-labelledby="label-select"
placeholderText={placeholder}
createText={createText}
>

View File

@ -40,9 +40,7 @@ function UserAccessListItem({ role, i18n, detailUrl, onSelect }) {
label={i18n._(t`Role`)}
value={
<Chip
isReadOnly={
!role.summary_fields.user_capabilities.unattach
}
key={role.name}
aria-label={role.name}
onClick={() => onSelect(role)}

View File

@ -117,7 +117,7 @@ function UserFormFields({ user, i18n }) {
fieldId="user-type"
helperTextInvalid={userTypeMeta.error}
isRequired
isValid={!userTypeMeta.touched || !userTypeMeta.error}
validated={(!userTypeMeta.touched || !userTypeMeta.error) ? 'default' : 'error'}
label={i18n._(t`User Type`)}
>
<AnsibleSelect