mirror of
https://github.com/ansible/awx.git
synced 2026-01-26 16:11:30 -03:30
after running pf code mod tool to auto update files to conform to v4 and a few manual tweaks
This commit is contained in:
parent
475b733890
commit
e49a99e0f6
@ -67,9 +67,9 @@ export default function AlertModal({
|
||||
return (
|
||||
<Modal
|
||||
header={customHeader}
|
||||
isFooterLeftAligned
|
||||
|
||||
isOpen={Boolean(isOpen)}
|
||||
isSmall
|
||||
variant="small"
|
||||
title={title}
|
||||
{...props}
|
||||
>
|
||||
|
||||
@ -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}
|
||||
>
|
||||
|
||||
@ -74,8 +74,8 @@ function AssociateModal({
|
||||
return (
|
||||
<Fragment>
|
||||
<Modal
|
||||
isFooterLeftAligned
|
||||
isLarge
|
||||
|
||||
variant="large"
|
||||
title={title}
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleClose}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -14,7 +14,7 @@ function PasswordField(props) {
|
||||
fieldId={id}
|
||||
helperTextInvalid={meta.error}
|
||||
isRequired={isRequired}
|
||||
isValid={isValid}
|
||||
validated={(isValid) ? 'default' : 'error'}
|
||||
label={label}
|
||||
>
|
||||
<InputGroup>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 => (
|
||||
|
||||
@ -84,7 +84,7 @@ function CredentialLookup({
|
||||
<FormGroup
|
||||
fieldId="credential"
|
||||
isRequired={required}
|
||||
isValid={isValid}
|
||||
validated={(isValid) ? 'default' : 'error'}
|
||||
label={label}
|
||||
helperTextInvalid={helperTextInvalid}
|
||||
>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -49,7 +49,7 @@ function OrganizationLookup({
|
||||
fieldId="organization"
|
||||
helperTextInvalid={helperTextInvalid}
|
||||
isRequired={required}
|
||||
isValid={isValid}
|
||||
validated={(isValid) ? 'default' : 'error'}
|
||||
label={i18n._(t`Organization`)}
|
||||
>
|
||||
<Lookup
|
||||
|
||||
@ -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} />}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -59,7 +59,7 @@ class ResourceAccessListItem extends React.Component {
|
||||
return (
|
||||
<Chip
|
||||
key={role.id}
|
||||
isReadOnly={!role.user_capabilities.unattach}
|
||||
|
||||
onClick={() => {
|
||||
onRoleDelete(role, accessRecord);
|
||||
}}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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>
|
||||
));
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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`)}
|
||||
>
|
||||
|
||||
@ -229,7 +229,7 @@ export const VerbosityField = withI18n()(({ i18n }) => {
|
||||
return (
|
||||
<FormGroup
|
||||
fieldId="verbosity"
|
||||
isValid={isValid}
|
||||
validated={(isValid) ? 'default' : 'error'}
|
||||
label={i18n._(t`Verbosity`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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 ? (
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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`)}
|
||||
|
||||
@ -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>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
}
|
||||
|
||||
@ -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>
|
||||
}
|
||||
|
||||
@ -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={[
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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={[
|
||||
|
||||
@ -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={[
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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);
|
||||
}}
|
||||
|
||||
@ -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}
|
||||
>
|
||||
|
||||
@ -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)}
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user