mirror of
https://github.com/ansible/awx.git
synced 2026-02-17 11:10:03 -03:30
Merge FieldTooltip and DetailPopover into single Popover component
This commit is contained in:
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
|
|||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { Form, FormGroup } from '@patternfly/react-core';
|
import { Form, FormGroup } from '@patternfly/react-core';
|
||||||
import { CredentialsAPI } from '../../api';
|
import { CredentialsAPI } from '../../api';
|
||||||
import { FieldTooltip } from '../FormField';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
import { getQSConfig, parseQueryString, mergeParams } from '../../util/qs';
|
import { getQSConfig, parseQueryString, mergeParams } from '../../util/qs';
|
||||||
import useRequest from '../../util/useRequest';
|
import useRequest from '../../util/useRequest';
|
||||||
@@ -72,7 +72,7 @@ function AdHocCredentialStep({ i18n, credentialTypeId, onEnableLaunch }) {
|
|||||||
}
|
}
|
||||||
helperTextInvalid={credentialMeta.error}
|
helperTextInvalid={credentialMeta.error}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Select the credential you want to use when accessing the remote hosts to run the command. Choose the credential containing the username and SSH key or password that Ansible will need to log into the remote hosts.`
|
t`Select the credential you want to use when accessing the remote hosts to run the command. Choose the credential containing the username and SSH key or password that Ansible will need to log into the remote hosts.`
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ import styled from 'styled-components';
|
|||||||
|
|
||||||
import { BrandName } from '../../variables';
|
import { BrandName } from '../../variables';
|
||||||
import AnsibleSelect from '../AnsibleSelect';
|
import AnsibleSelect from '../AnsibleSelect';
|
||||||
import FormField, { FieldTooltip } from '../FormField';
|
import FormField from '../FormField';
|
||||||
import { VariablesField } from '../CodeMirrorInput';
|
import { VariablesField } from '../CodeMirrorInput';
|
||||||
import {
|
import {
|
||||||
FormColumnLayout,
|
FormColumnLayout,
|
||||||
FormFullWidthLayout,
|
FormFullWidthLayout,
|
||||||
FormCheckboxLayout,
|
FormCheckboxLayout,
|
||||||
} from '../FormLayout';
|
} from '../FormLayout';
|
||||||
|
import Popover from '../Popover';
|
||||||
import { required } from '../../util/validators';
|
import { required } from '../../util/validators';
|
||||||
|
|
||||||
const TooltipWrapper = styled.div`
|
const TooltipWrapper = styled.div`
|
||||||
@@ -68,7 +69,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
|
|||||||
: 'error'
|
: 'error'
|
||||||
}
|
}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`These are the modules that ${brandName} supports running commands against.`
|
t`These are the modules that ${brandName} supports running commands against.`
|
||||||
)}
|
)}
|
||||||
@@ -146,7 +147,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
|
|||||||
}
|
}
|
||||||
helperTextInvalid={verbosityMeta.error}
|
helperTextInvalid={verbosityMeta.error}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`These are the verbosity levels for standard out of the command run that are supported.`
|
t`These are the verbosity levels for standard out of the command run that are supported.`
|
||||||
)}
|
)}
|
||||||
@@ -211,7 +212,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
|
|||||||
label={i18n._(t`Show changes`)}
|
label={i18n._(t`Show changes`)}
|
||||||
aria-label={i18n._(t`Show changes`)}
|
aria-label={i18n._(t`Show changes`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansible’s --diff mode.`
|
t`If enabled, show the changes made by Ansible tasks, where supported. This is equivalent to Ansible’s --diff mode.`
|
||||||
)}
|
)}
|
||||||
@@ -238,7 +239,7 @@ function AdHocDetailsStep({ i18n, verbosityOptions, moduleOptions }) {
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Enable privilege escalation`)}
|
{i18n._(t`Enable privilege escalation`)}
|
||||||
|
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={
|
content={
|
||||||
<p>
|
<p>
|
||||||
{i18n._(t`Enables creation of a provisioning
|
{i18n._(t`Enables creation of a provisioning
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
import { FieldTooltip } from '../FormField';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
function CodeMirrorField({
|
function CodeMirrorField({
|
||||||
id,
|
id,
|
||||||
@@ -37,7 +37,7 @@ function CodeMirrorField({
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={<FieldTooltip content={tooltip} />}
|
labelIcon={<Popover content={tooltip} />}
|
||||||
>
|
>
|
||||||
<CodeMirrorInput
|
<CodeMirrorInput
|
||||||
id={id}
|
id={id}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { node, number, oneOfType, shape, string, arrayOf } from 'prop-types';
|
|||||||
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
|
||||||
import { DetailName, DetailValue } from '../DetailList';
|
import { DetailName, DetailValue } from '../DetailList';
|
||||||
import MultiButtonToggle from '../MultiButtonToggle';
|
import MultiButtonToggle from '../MultiButtonToggle';
|
||||||
import DetailPopover from '../DetailPopover';
|
import Popover from '../Popover';
|
||||||
import {
|
import {
|
||||||
yamlToJson,
|
yamlToJson,
|
||||||
jsonToYaml,
|
jsonToYaml,
|
||||||
@@ -69,7 +69,7 @@ function VariablesDetail({ dataCy, helpText, value, label, rows, fullHeight }) {
|
|||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
{helpText && (
|
{helpText && (
|
||||||
<DetailPopover header={label} content={helpText} id={dataCy} />
|
<Popover header={label} content={helpText} id={dataCy} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
@@ -122,9 +122,13 @@ VariablesDetail.propTypes = {
|
|||||||
value: oneOfType([shape({}), arrayOf(string), string]).isRequired,
|
value: oneOfType([shape({}), arrayOf(string), string]).isRequired,
|
||||||
label: node.isRequired,
|
label: node.isRequired,
|
||||||
rows: number,
|
rows: number,
|
||||||
|
dataCy: string,
|
||||||
|
helpText: string,
|
||||||
};
|
};
|
||||||
VariablesDetail.defaultProps = {
|
VariablesDetail.defaultProps = {
|
||||||
rows: null,
|
rows: null,
|
||||||
|
dataCy: '',
|
||||||
|
helpText: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VariablesDetail;
|
export default VariablesDetail;
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import { t } from '@lingui/macro';
|
|||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Split, SplitItem } from '@patternfly/react-core';
|
import { Split, SplitItem } from '@patternfly/react-core';
|
||||||
import { CheckboxField, FieldTooltip } from '../FormField';
|
import { CheckboxField } from '../FormField';
|
||||||
import MultiButtonToggle from '../MultiButtonToggle';
|
import MultiButtonToggle from '../MultiButtonToggle';
|
||||||
import { yamlToJson, jsonToYaml, isJsonString } from '../../util/yaml';
|
import { yamlToJson, jsonToYaml, isJsonString } from '../../util/yaml';
|
||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
|
import Popover from '../Popover';
|
||||||
import { JSON_MODE, YAML_MODE } from './constants';
|
import { JSON_MODE, YAML_MODE } from './constants';
|
||||||
|
|
||||||
const FieldHeader = styled.div`
|
const FieldHeader = styled.div`
|
||||||
@@ -43,7 +44,7 @@ function VariablesField({
|
|||||||
<label htmlFor={id} className="pf-c-form__label">
|
<label htmlFor={id} className="pf-c-form__label">
|
||||||
<span className="pf-c-form__label-text">{label}</span>
|
<span className="pf-c-form__label-text">{label}</span>
|
||||||
</label>
|
</label>
|
||||||
{tooltip && <FieldTooltip content={tooltip} />}
|
{tooltip && <Popover content={tooltip} id={id} />}
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<MultiButtonToggle
|
<MultiButtonToggle
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ describe('VariablesField', () => {
|
|||||||
)}
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
expect(wrapper.find('Popover').length).toBe(1);
|
expect(wrapper.find('Popover[data-cy="the-field"]').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should submit value through Formik', async () => {
|
it('should submit value through Formik', async () => {
|
||||||
|
|||||||
@@ -1,17 +1,30 @@
|
|||||||
import 'styled-components/macro';
|
import 'styled-components/macro';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shape, node, number, oneOf } from 'prop-types';
|
import { shape, node, number, oneOf, string } from 'prop-types';
|
||||||
import { TextListItemVariants } from '@patternfly/react-core';
|
import { TextListItemVariants } from '@patternfly/react-core';
|
||||||
import { DetailName, DetailValue } from './Detail';
|
import { DetailName, DetailValue } from './Detail';
|
||||||
import CodeMirrorInput from '../CodeMirrorInput';
|
import CodeMirrorInput from '../CodeMirrorInput';
|
||||||
|
import Popover from '../Popover';
|
||||||
|
|
||||||
|
function CodeDetail({
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
mode,
|
||||||
|
rows,
|
||||||
|
fullHeight,
|
||||||
|
helpText,
|
||||||
|
dataCy,
|
||||||
|
}) {
|
||||||
|
const labelCy = dataCy ? `${dataCy}-label` : null;
|
||||||
|
const valueCy = dataCy ? `${dataCy}-value` : null;
|
||||||
|
|
||||||
function CodeDetail({ value, label, mode, rows, fullHeight }) {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DetailName
|
<DetailName
|
||||||
component={TextListItemVariants.dt}
|
component={TextListItemVariants.dt}
|
||||||
fullWidth
|
fullWidth
|
||||||
css="grid-column: 1 / -1"
|
css="grid-column: 1 / -1"
|
||||||
|
data-cy={labelCy}
|
||||||
>
|
>
|
||||||
<div className="pf-c-form__label">
|
<div className="pf-c-form__label">
|
||||||
<span
|
<span
|
||||||
@@ -20,12 +33,16 @@ function CodeDetail({ value, label, mode, rows, fullHeight }) {
|
|||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
|
{helpText && (
|
||||||
|
<Popover header={label} content={helpText} id={dataCy} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</DetailName>
|
</DetailName>
|
||||||
<DetailValue
|
<DetailValue
|
||||||
component={TextListItemVariants.dd}
|
component={TextListItemVariants.dd}
|
||||||
fullWidth
|
fullWidth
|
||||||
css="grid-column: 1 / -1; margin-top: -20px"
|
css="grid-column: 1 / -1; margin-top: -20px"
|
||||||
|
data-cy={valueCy}
|
||||||
>
|
>
|
||||||
<CodeMirrorInput
|
<CodeMirrorInput
|
||||||
mode={mode}
|
mode={mode}
|
||||||
@@ -42,11 +59,15 @@ function CodeDetail({ value, label, mode, rows, fullHeight }) {
|
|||||||
CodeDetail.propTypes = {
|
CodeDetail.propTypes = {
|
||||||
value: shape.isRequired,
|
value: shape.isRequired,
|
||||||
label: node.isRequired,
|
label: node.isRequired,
|
||||||
|
dataCy: string,
|
||||||
|
helpText: string,
|
||||||
rows: number,
|
rows: number,
|
||||||
mode: oneOf(['json', 'yaml', 'jinja2']).isRequired,
|
mode: oneOf(['json', 'yaml', 'jinja2']).isRequired,
|
||||||
};
|
};
|
||||||
CodeDetail.defaultProps = {
|
CodeDetail.defaultProps = {
|
||||||
rows: null,
|
rows: null,
|
||||||
|
helpText: '',
|
||||||
|
dataCy: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CodeDetail;
|
export default CodeDetail;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { node, bool, string } from 'prop-types';
|
import { node, bool, string } from 'prop-types';
|
||||||
import { TextListItem, TextListItemVariants } from '@patternfly/react-core';
|
import { TextListItem, TextListItemVariants } from '@patternfly/react-core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import DetailPopover from '../DetailPopover';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
const DetailName = styled(({ fullWidth, ...props }) => (
|
const DetailName = styled(({ fullWidth, ...props }) => (
|
||||||
<TextListItem {...props} />
|
<TextListItem {...props} />
|
||||||
@@ -61,9 +61,7 @@ const Detail = ({
|
|||||||
id={dataCy}
|
id={dataCy}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
{helpText && (
|
{helpText && <Popover header={label} content={helpText} id={dataCy} />}
|
||||||
<DetailPopover header={label} content={helpText} id={dataCy} />
|
|
||||||
)}
|
|
||||||
</DetailName>
|
</DetailName>
|
||||||
<DetailValue
|
<DetailValue
|
||||||
className={className}
|
className={className}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { node, string } from 'prop-types';
|
|
||||||
import { Button as _Button, Popover } from '@patternfly/react-core';
|
|
||||||
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
const Button = styled(_Button)`
|
|
||||||
--pf-c-button--PaddingTop: 0;
|
|
||||||
--pf-c-button--PaddingBottom: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function DetailPopover({ header, content, id }) {
|
|
||||||
const [showPopover, setShowPopover] = useState(false);
|
|
||||||
if (!content) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
bodyContent={content}
|
|
||||||
headerContent={header}
|
|
||||||
hideOnOutsideClick
|
|
||||||
id={id}
|
|
||||||
isVisible={showPopover}
|
|
||||||
shouldClose={() => setShowPopover(false)}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
onClick={() => setShowPopover(!showPopover)}
|
|
||||||
variant="plain"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded={showPopover}
|
|
||||||
>
|
|
||||||
<OutlinedQuestionCircleIcon
|
|
||||||
onClick={() => setShowPopover(!showPopover)}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
</Popover>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
DetailPopover.propTypes = {
|
|
||||||
content: node,
|
|
||||||
header: node,
|
|
||||||
id: string,
|
|
||||||
};
|
|
||||||
DetailPopover.defaultProps = {
|
|
||||||
content: null,
|
|
||||||
header: null,
|
|
||||||
id: 'detail-popover',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DetailPopover;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './DetailPopover';
|
|
||||||
@@ -3,7 +3,8 @@ import { bool, node, string } from 'prop-types';
|
|||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { CheckboxField, FieldTooltip } from '../FormField';
|
import { CheckboxField } from '../FormField';
|
||||||
|
import Popover from '../Popover';
|
||||||
|
|
||||||
const FieldHeader = styled.div`
|
const FieldHeader = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -38,7 +39,7 @@ function FieldWithPrompt({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</label>
|
</label>
|
||||||
{tooltip && <FieldTooltip content={tooltip} />}
|
{tooltip && <Popover content={tooltip} id={fieldId} />}
|
||||||
</div>
|
</div>
|
||||||
<StyledCheckboxField
|
<StyledCheckboxField
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe('FieldWithPrompt', () => {
|
|||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Required asterisk and Tooltip hidden when not required and tooltip not provided', () => {
|
test('Required asterisk and Popover hidden when not required and tooltip not provided', () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
@@ -33,10 +33,10 @@ describe('FieldWithPrompt', () => {
|
|||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.pf-c-form__label-required')).toHaveLength(0);
|
expect(wrapper.find('.pf-c-form__label-required')).toHaveLength(0);
|
||||||
expect(wrapper.find('Tooltip')).toHaveLength(0);
|
expect(wrapper.find('Popover')).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Required asterisk and Tooltip shown when required and tooltip provided', () => {
|
test('Required asterisk and Popover shown when required and tooltip provided', () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
@@ -61,6 +61,8 @@ describe('FieldWithPrompt', () => {
|
|||||||
</Formik>
|
</Formik>
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.pf-c-form__label-required')).toHaveLength(1);
|
expect(wrapper.find('.pf-c-form__label-required')).toHaveLength(1);
|
||||||
expect(wrapper.find('Popover')).toHaveLength(1);
|
expect(wrapper.find('Popover[data-cy="job-template-limit"]').length).toBe(
|
||||||
|
1
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { FormGroup, TextArea } from '@patternfly/react-core';
|
import { FormGroup, TextArea } from '@patternfly/react-core';
|
||||||
import FieldTooltip from './FieldTooltip';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
function ArrayTextField(props) {
|
function ArrayTextField(props) {
|
||||||
const {
|
const {
|
||||||
@@ -30,7 +30,7 @@ function ArrayTextField(props) {
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />}
|
labelIcon={<Popover content={tooltip} maxWidth={tooltipMaxWidth} />}
|
||||||
>
|
>
|
||||||
<TextArea
|
<TextArea
|
||||||
id={id}
|
id={id}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { string, func, node } from 'prop-types';
|
import { string, func, node } from 'prop-types';
|
||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { Checkbox, Tooltip } from '@patternfly/react-core';
|
import { Checkbox } from '@patternfly/react-core';
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
import Popover from '../Popover';
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function CheckboxField({
|
function CheckboxField({
|
||||||
id,
|
id,
|
||||||
@@ -27,11 +22,7 @@ function CheckboxField({
|
|||||||
<span>
|
<span>
|
||||||
{label}
|
{label}
|
||||||
|
|
||||||
{tooltip && (
|
{tooltip && <Popover content={tooltip} />}
|
||||||
<Tooltip position="right" content={tooltip}>
|
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
id={id}
|
id={id}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { node } from 'prop-types';
|
|
||||||
import { Popover } from '@patternfly/react-core';
|
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function FieldTooltip({ content, ...rest }) {
|
|
||||||
const [showTooltip, setShowTooltip] = useState(false);
|
|
||||||
if (!content) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
bodyContent={content}
|
|
||||||
isVisible={showTooltip}
|
|
||||||
hideOnOutsideClick
|
|
||||||
shouldClose={() => setShowTooltip(false)}
|
|
||||||
{...rest}
|
|
||||||
>
|
|
||||||
<QuestionCircleIcon onClick={() => setShowTooltip(!showTooltip)} />
|
|
||||||
</Popover>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
FieldTooltip.propTypes = {
|
|
||||||
content: node,
|
|
||||||
};
|
|
||||||
FieldTooltip.defaultProps = {
|
|
||||||
content: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FieldTooltip;
|
|
||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { FormGroup, TextInput, TextArea } from '@patternfly/react-core';
|
import { FormGroup, TextInput, TextArea } from '@patternfly/react-core';
|
||||||
import FieldTooltip from './FieldTooltip';
|
import Popover from '../Popover';
|
||||||
|
|
||||||
function FormField(props) {
|
function FormField(props) {
|
||||||
const {
|
const {
|
||||||
@@ -31,9 +31,7 @@ function FormField(props) {
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={
|
labelIcon={<Popover content={tooltip} maxWidth={tooltipMaxWidth} />}
|
||||||
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<TextArea
|
<TextArea
|
||||||
id={id}
|
id={id}
|
||||||
@@ -55,9 +53,7 @@ function FormField(props) {
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={
|
labelIcon={<Popover content={tooltip} maxWidth={tooltipMaxWidth} />}
|
||||||
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
id={id}
|
id={id}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { FormGroup, InputGroup } from '@patternfly/react-core';
|
import { FormGroup, InputGroup } from '@patternfly/react-core';
|
||||||
|
import Popover from '../Popover';
|
||||||
import PasswordInput from './PasswordInput';
|
import PasswordInput from './PasswordInput';
|
||||||
|
|
||||||
function PasswordField(props) {
|
function PasswordField(props) {
|
||||||
const { id, name, label, validate, isRequired } = props;
|
const { id, name, label, validate, isRequired, helperText } = props;
|
||||||
const [, meta] = useField({ name, validate });
|
const [, meta] = useField({ name, validate });
|
||||||
const isValid = !(meta.touched && meta.error);
|
const isValid = !(meta.touched && meta.error);
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ function PasswordField(props) {
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
|
labelIcon={helperText && <Popover content={helperText} />}
|
||||||
>
|
>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<PasswordInput {...props} />
|
<PasswordInput {...props} />
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
export { default } from './FormField';
|
export { default } from './FormField';
|
||||||
export { default as CheckboxField } from './CheckboxField';
|
export { default as CheckboxField } from './CheckboxField';
|
||||||
export { default as FieldTooltip } from './FieldTooltip';
|
|
||||||
export { default as PasswordField } from './PasswordField';
|
export { default as PasswordField } from './PasswordField';
|
||||||
export { default as PasswordInput } from './PasswordInput';
|
export { default as PasswordInput } from './PasswordInput';
|
||||||
export { default as FormSubmitError } from './FormSubmitError';
|
export { default as FormSubmitError } from './FormSubmitError';
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import { withI18n } from '@lingui/react';
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
|
||||||
import { Form, FormGroup } from '@patternfly/react-core';
|
import { Form, FormGroup } from '@patternfly/react-core';
|
||||||
import FormField, { FormSubmitError, FieldTooltip } from '../FormField';
|
import FormField, { FormSubmitError } from '../FormField';
|
||||||
import FormActionGroup from '../FormActionGroup/FormActionGroup';
|
import FormActionGroup from '../FormActionGroup/FormActionGroup';
|
||||||
import { VariablesField } from '../CodeMirrorInput';
|
import { VariablesField } from '../CodeMirrorInput';
|
||||||
import { InventoryLookup } from '../Lookup';
|
import { InventoryLookup } from '../Lookup';
|
||||||
import { FormColumnLayout, FormFullWidthLayout } from '../FormLayout';
|
import { FormColumnLayout, FormFullWidthLayout } from '../FormLayout';
|
||||||
|
import Popover from '../Popover';
|
||||||
import { required } from '../../util/validators';
|
import { required } from '../../util/validators';
|
||||||
|
|
||||||
const InventoryLookupField = withI18n()(({ i18n, host }) => {
|
const InventoryLookupField = withI18n()(({ i18n, host }) => {
|
||||||
@@ -26,7 +27,7 @@ const InventoryLookupField = withI18n()(({ i18n, host }) => {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={i18n._(t`Inventory`)}
|
label={i18n._(t`Inventory`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Select the inventory that this host will belong to.`
|
t`Select the inventory that this host will belong to.`
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { t } from '@lingui/macro';
|
|||||||
import { useField } from 'formik';
|
import { useField } from 'formik';
|
||||||
import { Form, FormGroup, Switch } from '@patternfly/react-core';
|
import { Form, FormGroup, Switch } from '@patternfly/react-core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import FormField, { FieldTooltip } from '../../FormField';
|
import FormField from '../../FormField';
|
||||||
import { TagMultiSelect } from '../../MultiSelect';
|
import { TagMultiSelect } from '../../MultiSelect';
|
||||||
import AnsibleSelect from '../../AnsibleSelect';
|
import AnsibleSelect from '../../AnsibleSelect';
|
||||||
import { VariablesField } from '../../CodeMirrorInput';
|
import { VariablesField } from '../../CodeMirrorInput';
|
||||||
|
import Popover from '../../Popover';
|
||||||
|
|
||||||
const FieldHeader = styled.div`
|
const FieldHeader = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -104,7 +105,7 @@ function JobTypeField({ i18n }) {
|
|||||||
fieldId="propmt-job-type"
|
fieldId="propmt-job-type"
|
||||||
label={i18n._(t`Job Type`)}
|
label={i18n._(t`Job Type`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`For job templates, select run to execute the playbook.
|
content={i18n._(t`For job templates, select run to execute the playbook.
|
||||||
Select check to only check playbook syntax, test environment setup,
|
Select check to only check playbook syntax, test environment setup,
|
||||||
and report problems without executing the playbook.`)}
|
and report problems without executing the playbook.`)}
|
||||||
@@ -141,7 +142,7 @@ function VerbosityField({ i18n }) {
|
|||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={i18n._(t`Verbosity`)}
|
label={i18n._(t`Verbosity`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Control the level of output ansible
|
content={i18n._(t`Control the level of output ansible
|
||||||
will produce as the playbook executes.`)}
|
will produce as the playbook executes.`)}
|
||||||
/>
|
/>
|
||||||
@@ -166,7 +167,7 @@ function ShowChangesToggle({ i18n }) {
|
|||||||
<label className="pf-c-form__label" htmlFor="prompt-show-changes">
|
<label className="pf-c-form__label" htmlFor="prompt-show-changes">
|
||||||
<span className="pf-c-form__label-text">
|
<span className="pf-c-form__label-text">
|
||||||
{i18n._(t`Show Changes`)}
|
{i18n._(t`Show Changes`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`If enabled, show the changes made
|
content={i18n._(t`If enabled, show the changes made
|
||||||
by Ansible tasks, where supported. This is equivalent to Ansible’s
|
by Ansible tasks, where supported. This is equivalent to Ansible’s
|
||||||
--diff mode.`)}
|
--diff mode.`)}
|
||||||
@@ -192,7 +193,7 @@ function TagField({ id, name, label, tooltip }) {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
fieldId={id}
|
fieldId={id}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={<FieldTooltip content={tooltip} />}
|
labelIcon={<Popover content={tooltip} />}
|
||||||
>
|
>
|
||||||
<TagMultiSelect value={field.value} onChange={helpers.setValue} />
|
<TagMultiSelect value={field.value} onChange={helpers.setValue} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import {
|
|||||||
SelectOption,
|
SelectOption,
|
||||||
SelectVariant,
|
SelectVariant,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import FormField, { FieldTooltip } from '../../FormField';
|
import FormField from '../../FormField';
|
||||||
import AnsibleSelect from '../../AnsibleSelect';
|
import AnsibleSelect from '../../AnsibleSelect';
|
||||||
|
import Popover from '../../Popover';
|
||||||
import {
|
import {
|
||||||
required,
|
required,
|
||||||
minMaxValue,
|
minMaxValue,
|
||||||
@@ -99,7 +100,7 @@ function MultipleChoiceField({ question }) {
|
|||||||
isRequired={question.required}
|
isRequired={question.required}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={question.question_name}
|
label={question.question_name}
|
||||||
labelIcon={<FieldTooltip content={question.question_description} />}
|
labelIcon={<Popover content={question.question_description} />}
|
||||||
>
|
>
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
id={id}
|
id={id}
|
||||||
@@ -134,7 +135,7 @@ function MultiSelectField({ question, i18n }) {
|
|||||||
isRequired={question.required}
|
isRequired={question.required}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={question.question_name}
|
label={question.question_name}
|
||||||
labelIcon={<FieldTooltip content={question.question_description} />}
|
labelIcon={<Popover content={question.question_description} />}
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
variant={SelectVariant.typeaheadMulti}
|
variant={SelectVariant.typeaheadMulti}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { FormGroup } from '@patternfly/react-core';
|
|||||||
import { CredentialsAPI } from '../../api';
|
import { CredentialsAPI } from '../../api';
|
||||||
import { Credential } from '../../types';
|
import { Credential } from '../../types';
|
||||||
import { getQSConfig, parseQueryString, mergeParams } from '../../util/qs';
|
import { getQSConfig, parseQueryString, mergeParams } from '../../util/qs';
|
||||||
import { FieldTooltip } from '../FormField';
|
import Popover from '../Popover';
|
||||||
import Lookup from './Lookup';
|
import Lookup from './Lookup';
|
||||||
import OptionsList from '../OptionsList';
|
import OptionsList from '../OptionsList';
|
||||||
import useAutoPopulateLookup from '../../util/useAutoPopulateLookup';
|
import useAutoPopulateLookup from '../../util/useAutoPopulateLookup';
|
||||||
@@ -117,7 +117,7 @@ function CredentialLookup({
|
|||||||
isRequired={required}
|
isRequired={required}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={label}
|
label={label}
|
||||||
labelIcon={tooltip && <FieldTooltip content={tooltip} />}
|
labelIcon={tooltip && <Popover content={tooltip} />}
|
||||||
helperTextInvalid={helperTextInvalid}
|
helperTextInvalid={helperTextInvalid}
|
||||||
>
|
>
|
||||||
<Lookup
|
<Lookup
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { InstanceGroupsAPI } from '../../api';
|
import { InstanceGroupsAPI } from '../../api';
|
||||||
import { getQSConfig, parseQueryString } from '../../util/qs';
|
import { getQSConfig, parseQueryString } from '../../util/qs';
|
||||||
import { FieldTooltip } from '../FormField';
|
import Popover from '../Popover';
|
||||||
import OptionsList from '../OptionsList';
|
import OptionsList from '../OptionsList';
|
||||||
import useRequest from '../../util/useRequest';
|
import useRequest from '../../util/useRequest';
|
||||||
import Lookup from './Lookup';
|
import Lookup from './Lookup';
|
||||||
@@ -68,7 +68,7 @@ function InstanceGroupsLookup(props) {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
className={className}
|
className={className}
|
||||||
label={i18n._(t`Instance Groups`)}
|
label={i18n._(t`Instance Groups`)}
|
||||||
labelIcon={tooltip && <FieldTooltip content={tooltip} />}
|
labelIcon={tooltip && <Popover content={tooltip} />}
|
||||||
fieldId="org-instance-groups"
|
fieldId="org-instance-groups"
|
||||||
>
|
>
|
||||||
<Lookup
|
<Lookup
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { t } from '@lingui/macro';
|
|||||||
import { FormGroup } from '@patternfly/react-core';
|
import { FormGroup } from '@patternfly/react-core';
|
||||||
import { ProjectsAPI } from '../../api';
|
import { ProjectsAPI } from '../../api';
|
||||||
import { Project } from '../../types';
|
import { Project } from '../../types';
|
||||||
import { FieldTooltip } from '../FormField';
|
import Popover from '../Popover';
|
||||||
import OptionsList from '../OptionsList';
|
import OptionsList from '../OptionsList';
|
||||||
import useAutoPopulateLookup from '../../util/useAutoPopulateLookup';
|
import useAutoPopulateLookup from '../../util/useAutoPopulateLookup';
|
||||||
import useRequest from '../../util/useRequest';
|
import useRequest from '../../util/useRequest';
|
||||||
@@ -80,7 +80,7 @@ function ProjectLookup({
|
|||||||
isRequired={required}
|
isRequired={required}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={i18n._(t`Project`)}
|
label={i18n._(t`Project`)}
|
||||||
labelIcon={tooltip && <FieldTooltip content={tooltip} />}
|
labelIcon={tooltip && <Popover content={tooltip} />}
|
||||||
>
|
>
|
||||||
<Lookup
|
<Lookup
|
||||||
id="project"
|
id="project"
|
||||||
|
|||||||
51
awx/ui_next/src/components/Popover/Popover.jsx
Normal file
51
awx/ui_next/src/components/Popover/Popover.jsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { node, string } from 'prop-types';
|
||||||
|
import { Popover as PFPopover } from '@patternfly/react-core';
|
||||||
|
import { HelpIcon } from '@patternfly/react-icons';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const PopoverButton = styled.button`
|
||||||
|
padding: var(--pf-global--spacer--xs);
|
||||||
|
margin: -(var(--pf-global--spacer--xs));
|
||||||
|
`;
|
||||||
|
|
||||||
|
function Popover({ content, header, id, maxWidth, ...rest }) {
|
||||||
|
if (!content) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<PFPopover
|
||||||
|
bodyContent={content}
|
||||||
|
headerContent={header}
|
||||||
|
hideOnOutsideClick
|
||||||
|
id={id}
|
||||||
|
data-cy={id}
|
||||||
|
maxWidth={maxWidth}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<PopoverButton
|
||||||
|
aria-haspopup="true"
|
||||||
|
className="pf-c-form__group-label-help"
|
||||||
|
onClick={e => e.preventDefault()}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<HelpIcon noVerticalAlign />
|
||||||
|
</PopoverButton>
|
||||||
|
</PFPopover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Popover.propTypes = {
|
||||||
|
content: node,
|
||||||
|
header: node,
|
||||||
|
id: string,
|
||||||
|
maxWidth: string,
|
||||||
|
};
|
||||||
|
Popover.defaultProps = {
|
||||||
|
content: null,
|
||||||
|
header: null,
|
||||||
|
id: '',
|
||||||
|
maxWidth: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Popover;
|
||||||
1
awx/ui_next/src/components/Popover/index.js
Normal file
1
awx/ui_next/src/components/Popover/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './Popover';
|
||||||
@@ -7,14 +7,12 @@ import { Form, FormGroup } from '@patternfly/react-core';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { required } from '../../../util/validators';
|
import { required } from '../../../util/validators';
|
||||||
import FormField, {
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
FormSubmitError,
|
|
||||||
FieldTooltip,
|
|
||||||
} from '../../../components/FormField';
|
|
||||||
import { FormColumnLayout } from '../../../components/FormLayout';
|
import { FormColumnLayout } from '../../../components/FormLayout';
|
||||||
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||||
import OrganizationLookup from '../../../components/Lookup/OrganizationLookup';
|
import OrganizationLookup from '../../../components/Lookup/OrganizationLookup';
|
||||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
|
|
||||||
function ApplicationFormFields({
|
function ApplicationFormFields({
|
||||||
i18n,
|
i18n,
|
||||||
@@ -85,7 +83,7 @@ function ApplicationFormFields({
|
|||||||
isRequired
|
isRequired
|
||||||
label={i18n._(t`Authorization grant type`)}
|
label={i18n._(t`Authorization grant type`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`The Grant type the user must use for acquire tokens for this application`
|
t`The Grant type the user must use for acquire tokens for this application`
|
||||||
)}
|
)}
|
||||||
@@ -129,7 +127,7 @@ function ApplicationFormFields({
|
|||||||
isRequired
|
isRequired
|
||||||
label={i18n._(t`Client type`)}
|
label={i18n._(t`Client type`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Set to Public or Confidential depending on how secure the client device is.`
|
t`Set to Public or Confidential depending on how secure the client device is.`
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
SelectOption,
|
SelectOption,
|
||||||
SelectVariant,
|
SelectVariant,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { FieldTooltip } from '../../../../components/FormField';
|
import Popover from '../../../../components/Popover';
|
||||||
|
|
||||||
function BecomeMethodField({ fieldOptions, isRequired }) {
|
function BecomeMethodField({ fieldOptions, isRequired }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
@@ -36,9 +36,7 @@ function BecomeMethodField({ fieldOptions, isRequired }) {
|
|||||||
helperTextInvalid={meta.error}
|
helperTextInvalid={meta.error}
|
||||||
label={fieldOptions.label}
|
label={fieldOptions.label}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
fieldOptions.help_text && (
|
fieldOptions.help_text && <Popover content={fieldOptions.help_text} />
|
||||||
<FieldTooltip content={fieldOptions.help_text} />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={!(meta.touched && meta.error) ? 'default' : 'error'}
|
validated={!(meta.touched && meta.error) ? 'default' : 'error'}
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ import {
|
|||||||
InputGroup,
|
InputGroup,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { FieldTooltip, PasswordInput } from '../../../../components/FormField';
|
import { PasswordInput } from '../../../../components/FormField';
|
||||||
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
||||||
|
import Popover from '../../../../components/Popover';
|
||||||
import { CredentialType } from '../../../../types';
|
import { CredentialType } from '../../../../types';
|
||||||
import { required } from '../../../../util/validators';
|
import { required } from '../../../../util/validators';
|
||||||
import { CredentialPluginField } from '../CredentialPlugins';
|
import { CredentialPluginField } from '../CredentialPlugins';
|
||||||
@@ -140,9 +141,7 @@ function CredentialField({ credentialType, fieldOptions, i18n }) {
|
|||||||
helperTextInvalid={meta.error}
|
helperTextInvalid={meta.error}
|
||||||
label={fieldOptions.label}
|
label={fieldOptions.label}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
fieldOptions.help_text && (
|
fieldOptions.help_text && <Popover content={fieldOptions.help_text} />
|
||||||
<FieldTooltip content={fieldOptions.help_text} />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { KeyIcon } from '@patternfly/react-icons';
|
import { KeyIcon } from '@patternfly/react-icons';
|
||||||
import { FieldTooltip } from '../../../../components/FormField';
|
|
||||||
import FieldWithPrompt from '../../../../components/FieldWithPrompt';
|
import FieldWithPrompt from '../../../../components/FieldWithPrompt';
|
||||||
|
import Popover from '../../../../components/Popover';
|
||||||
import { CredentialPluginPrompt } from './CredentialPluginPrompt';
|
import { CredentialPluginPrompt } from './CredentialPluginPrompt';
|
||||||
import CredentialPluginSelected from './CredentialPluginSelected';
|
import CredentialPluginSelected from './CredentialPluginSelected';
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ function CredentialPluginField(props) {
|
|||||||
label={fieldOptions.label}
|
label={fieldOptions.label}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
fieldOptions.help_text && (
|
fieldOptions.help_text && (
|
||||||
<FieldTooltip content={fieldOptions.help_text} />
|
<Popover content={fieldOptions.help_text} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { useField, useFormikContext } from 'formik';
|
import { useField, useFormikContext } from 'formik';
|
||||||
import styled from 'styled-components';
|
import { Form, FormGroup } from '@patternfly/react-core';
|
||||||
import { Form, FormGroup, Tooltip } from '@patternfly/react-core';
|
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import { CredentialTypesAPI } from '../../../../../api';
|
import { CredentialTypesAPI } from '../../../../../api';
|
||||||
import AnsibleSelect from '../../../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../../../components/AnsibleSelect';
|
||||||
import ContentError from '../../../../../components/ContentError';
|
import ContentError from '../../../../../components/ContentError';
|
||||||
import ContentLoading from '../../../../../components/ContentLoading';
|
import ContentLoading from '../../../../../components/ContentLoading';
|
||||||
import FormField from '../../../../../components/FormField';
|
import FormField from '../../../../../components/FormField';
|
||||||
import { FormFullWidthLayout } from '../../../../../components/FormLayout';
|
import { FormFullWidthLayout } from '../../../../../components/FormLayout';
|
||||||
|
import Popover from '../../../../../components/Popover';
|
||||||
import useRequest from '../../../../../util/useRequest';
|
import useRequest from '../../../../../util/useRequest';
|
||||||
import { required } from '../../../../../util/validators';
|
import { required } from '../../../../../util/validators';
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function MetadataStep({ i18n }) {
|
function MetadataStep({ i18n }) {
|
||||||
const form = useFormikContext();
|
const form = useFormikContext();
|
||||||
const [selectedCredential] = useField('credential');
|
const [selectedCredential] = useField('credential');
|
||||||
@@ -82,12 +77,10 @@ function MetadataStep({ i18n }) {
|
|||||||
fieldId={`credential-${field.id}`}
|
fieldId={`credential-${field.id}`}
|
||||||
label={field.label}
|
label={field.label}
|
||||||
isRequired={field.required}
|
isRequired={field.required}
|
||||||
|
labelIcon={
|
||||||
|
field.help_text && <Popover content={field.help_text} />
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{field.help_text && (
|
|
||||||
<Tooltip content={field.help_text} position="right">
|
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
name={`inputs.${field.id}`}
|
name={`inputs.${field.id}`}
|
||||||
value={form.values.inputs[field.id]}
|
value={form.values.inputs[field.id]}
|
||||||
|
|||||||
@@ -1,29 +1,18 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import styled from 'styled-components';
|
|
||||||
import { func, shape } from 'prop-types';
|
import { func, shape } from 'prop-types';
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import {
|
import { Button, Form, FormGroup, Modal } from '@patternfly/react-core';
|
||||||
Button,
|
|
||||||
Form,
|
|
||||||
FormGroup,
|
|
||||||
Modal,
|
|
||||||
Tooltip,
|
|
||||||
} from '@patternfly/react-core';
|
|
||||||
import { QuestionCircleIcon as PFQuestionCircleIcon } from '@patternfly/react-icons';
|
|
||||||
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
|
import { CredentialsAPI, CredentialTypesAPI } from '../../../api';
|
||||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||||
import FormField from '../../../components/FormField';
|
import FormField from '../../../components/FormField';
|
||||||
import { FormFullWidthLayout } from '../../../components/FormLayout';
|
import { FormFullWidthLayout } from '../../../components/FormLayout';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import { required } from '../../../util/validators';
|
import { required } from '../../../util/validators';
|
||||||
import useRequest from '../../../util/useRequest';
|
import useRequest from '../../../util/useRequest';
|
||||||
import { CredentialPluginTestAlert } from './CredentialPlugins';
|
import { CredentialPluginTestAlert } from './CredentialPlugins';
|
||||||
|
|
||||||
const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
|
||||||
margin-left: 10px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function ExternalTestModal({
|
function ExternalTestModal({
|
||||||
i18n,
|
i18n,
|
||||||
credential,
|
credential,
|
||||||
@@ -124,12 +113,7 @@ function ExternalTestModal({
|
|||||||
label={field.label}
|
label={field.label}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
field.help_text && (
|
field.help_text && (
|
||||||
<Tooltip
|
<Popover content={field.help_text} />
|
||||||
content={field.help_text}
|
|
||||||
position="right"
|
|
||||||
>
|
|
||||||
<QuestionCircleIcon />
|
|
||||||
</Tooltip>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import ContentError from '../../../components/ContentError';
|
|||||||
import ContentLoading from '../../../components/ContentLoading';
|
import ContentLoading from '../../../components/ContentLoading';
|
||||||
import CredentialChip from '../../../components/CredentialChip';
|
import CredentialChip from '../../../components/CredentialChip';
|
||||||
import DeleteButton from '../../../components/DeleteButton';
|
import DeleteButton from '../../../components/DeleteButton';
|
||||||
import { FieldTooltip } from '../../../components/FormField';
|
|
||||||
import InventorySourceSyncButton from '../shared/InventorySourceSyncButton';
|
import InventorySourceSyncButton from '../shared/InventorySourceSyncButton';
|
||||||
import {
|
import {
|
||||||
DetailList,
|
DetailList,
|
||||||
@@ -19,6 +18,7 @@ import {
|
|||||||
UserDateDetail,
|
UserDateDetail,
|
||||||
} from '../../../components/DetailList';
|
} from '../../../components/DetailList';
|
||||||
import ErrorDetail from '../../../components/ErrorDetail';
|
import ErrorDetail from '../../../components/ErrorDetail';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import useRequest from '../../../util/useRequest';
|
import useRequest from '../../../util/useRequest';
|
||||||
import { InventorySourcesAPI } from '../../../api';
|
import { InventorySourcesAPI } from '../../../api';
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
|
|||||||
{overwrite && (
|
{overwrite && (
|
||||||
<ListItem>
|
<ListItem>
|
||||||
{i18n._(t`Overwrite`)}
|
{i18n._(t`Overwrite`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={
|
content={
|
||||||
<>
|
<>
|
||||||
{i18n._(t`If checked, any hosts and groups that were
|
{i18n._(t`If checked, any hosts and groups that were
|
||||||
@@ -135,7 +135,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
|
|||||||
{overwrite_vars && (
|
{overwrite_vars && (
|
||||||
<ListItem>
|
<ListItem>
|
||||||
{i18n._(t`Overwrite variables`)}
|
{i18n._(t`Overwrite variables`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={
|
content={
|
||||||
<>
|
<>
|
||||||
{i18n._(t`If checked, all variables for child groups
|
{i18n._(t`If checked, all variables for child groups
|
||||||
@@ -154,7 +154,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
|
|||||||
{update_on_launch && (
|
{update_on_launch && (
|
||||||
<ListItem>
|
<ListItem>
|
||||||
{i18n._(t`Update on launch`)}
|
{i18n._(t`Update on launch`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Each time a job runs using this inventory,
|
content={i18n._(t`Each time a job runs using this inventory,
|
||||||
refresh the inventory from the selected source before
|
refresh the inventory from the selected source before
|
||||||
executing job tasks.`)}
|
executing job tasks.`)}
|
||||||
@@ -164,7 +164,7 @@ function InventorySourceDetail({ inventorySource, i18n }) {
|
|||||||
{update_on_project_update && (
|
{update_on_project_update && (
|
||||||
<ListItem>
|
<ListItem>
|
||||||
{i18n._(t`Update on project update`)}
|
{i18n._(t`Update on project update`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`After every project update where the SCM revision
|
content={i18n._(t`After every project update where the SCM revision
|
||||||
changes, refresh the inventory from the selected source
|
changes, refresh the inventory from the selected source
|
||||||
before executing job tasks. This is intended for static content,
|
before executing job tasks. This is intended for static content,
|
||||||
|
|||||||
@@ -13,14 +13,12 @@ import AnsibleSelect from '../../../components/AnsibleSelect';
|
|||||||
import ContentError from '../../../components/ContentError';
|
import ContentError from '../../../components/ContentError';
|
||||||
import ContentLoading from '../../../components/ContentLoading';
|
import ContentLoading from '../../../components/ContentLoading';
|
||||||
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||||
import FormField, {
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
FieldTooltip,
|
|
||||||
FormSubmitError,
|
|
||||||
} from '../../../components/FormField';
|
|
||||||
import {
|
import {
|
||||||
FormColumnLayout,
|
FormColumnLayout,
|
||||||
SubFormLayout,
|
SubFormLayout,
|
||||||
} from '../../../components/FormLayout';
|
} from '../../../components/FormLayout';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AzureSubForm,
|
AzureSubForm,
|
||||||
@@ -145,7 +143,7 @@ const InventorySourceFormFields = ({ source, sourceOptions, i18n }) => {
|
|||||||
fieldId="custom-virtualenv"
|
fieldId="custom-virtualenv"
|
||||||
label={i18n._(t`Ansible Environment`)}
|
label={i18n._(t`Ansible Environment`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Select the custom
|
content={i18n._(t`Select the custom
|
||||||
Python virtual environment for this
|
Python virtual environment for this
|
||||||
inventory source sync to run on.`)}
|
inventory source sync to run on.`)}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import useRequest from '../../../../util/useRequest';
|
|||||||
import { required } from '../../../../util/validators';
|
import { required } from '../../../../util/validators';
|
||||||
|
|
||||||
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
||||||
import { FieldTooltip } from '../../../../components/FormField';
|
|
||||||
import CredentialLookup from '../../../../components/Lookup/CredentialLookup';
|
import CredentialLookup from '../../../../components/Lookup/CredentialLookup';
|
||||||
import ProjectLookup from '../../../../components/Lookup/ProjectLookup';
|
import ProjectLookup from '../../../../components/Lookup/ProjectLookup';
|
||||||
|
import Popover from '../../../../components/Popover';
|
||||||
import {
|
import {
|
||||||
OptionsField,
|
OptionsField,
|
||||||
SourceVarsField,
|
SourceVarsField,
|
||||||
@@ -99,7 +99,7 @@ const SCMSubForm = ({ autoPopulateProject, i18n }) => {
|
|||||||
isRequired
|
isRequired
|
||||||
label={i18n._(t`Inventory file`)}
|
label={i18n._(t`Inventory file`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Select the inventory file
|
content={i18n._(t`Select the inventory file
|
||||||
to be synced by this source. You can select from
|
to be synced by this source. You can select from
|
||||||
the dropdown or enter a file within the input.`)}
|
the dropdown or enter a file within the input.`)}
|
||||||
|
|||||||
@@ -6,14 +6,12 @@ import { FormGroup } from '@patternfly/react-core';
|
|||||||
import { minMaxValue, regExp } from '../../../../util/validators';
|
import { minMaxValue, regExp } from '../../../../util/validators';
|
||||||
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
||||||
import { VariablesField } from '../../../../components/CodeMirrorInput';
|
import { VariablesField } from '../../../../components/CodeMirrorInput';
|
||||||
import FormField, {
|
import FormField, { CheckboxField } from '../../../../components/FormField';
|
||||||
CheckboxField,
|
|
||||||
FieldTooltip,
|
|
||||||
} from '../../../../components/FormField';
|
|
||||||
import {
|
import {
|
||||||
FormFullWidthLayout,
|
FormFullWidthLayout,
|
||||||
FormCheckboxLayout,
|
FormCheckboxLayout,
|
||||||
} from '../../../../components/FormLayout';
|
} from '../../../../components/FormLayout';
|
||||||
|
import Popover from '../../../../components/Popover';
|
||||||
|
|
||||||
export const SourceVarsField = withI18n()(({ i18n }) => (
|
export const SourceVarsField = withI18n()(({ i18n }) => (
|
||||||
<FormFullWidthLayout>
|
<FormFullWidthLayout>
|
||||||
@@ -39,7 +37,7 @@ export const VerbosityField = withI18n()(({ i18n }) => {
|
|||||||
validated={isValid ? 'default' : 'error'}
|
validated={isValid ? 'default' : 'error'}
|
||||||
label={i18n._(t`Verbosity`)}
|
label={i18n._(t`Verbosity`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Control the level of output Ansible
|
content={i18n._(t`Control the level of output Ansible
|
||||||
will produce for inventory source update jobs.`)}
|
will produce for inventory source update jobs.`)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ import AnsibleSelect from '../../../components/AnsibleSelect';
|
|||||||
import ContentError from '../../../components/ContentError';
|
import ContentError from '../../../components/ContentError';
|
||||||
import ContentLoading from '../../../components/ContentLoading';
|
import ContentLoading from '../../../components/ContentLoading';
|
||||||
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||||
import FormField, {
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
FieldTooltip,
|
|
||||||
FormSubmitError,
|
|
||||||
} from '../../../components/FormField';
|
|
||||||
import OrganizationLookup from '../../../components/Lookup/OrganizationLookup';
|
import OrganizationLookup from '../../../components/Lookup/OrganizationLookup';
|
||||||
import { CredentialTypesAPI, ProjectsAPI } from '../../../api';
|
import { CredentialTypesAPI, ProjectsAPI } from '../../../api';
|
||||||
import { required } from '../../../util/validators';
|
import { required } from '../../../util/validators';
|
||||||
@@ -21,6 +18,7 @@ import {
|
|||||||
FormColumnLayout,
|
FormColumnLayout,
|
||||||
SubFormLayout,
|
SubFormLayout,
|
||||||
} from '../../../components/FormLayout';
|
} from '../../../components/FormLayout';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import {
|
import {
|
||||||
GitSubForm,
|
GitSubForm,
|
||||||
HgSubForm,
|
HgSubForm,
|
||||||
@@ -283,7 +281,7 @@ function ProjectFormFields({
|
|||||||
fieldId="project-custom-virtualenv"
|
fieldId="project-custom-virtualenv"
|
||||||
label={i18n._(t`Ansible Environment`)}
|
label={i18n._(t`Ansible Environment`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Select the playbook to be executed by
|
content={i18n._(t`Select the playbook to be executed by
|
||||||
this job.`)}
|
this job.`)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import { useField } from 'formik';
|
|||||||
import { FormGroup, Alert } from '@patternfly/react-core';
|
import { FormGroup, Alert } from '@patternfly/react-core';
|
||||||
import { required } from '../../../../util/validators';
|
import { required } from '../../../../util/validators';
|
||||||
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../../components/AnsibleSelect';
|
||||||
import FormField, { FieldTooltip } from '../../../../components/FormField';
|
import FormField from '../../../../components/FormField';
|
||||||
|
import Popover from '../../../../components/Popover';
|
||||||
import { BrandName } from '../../../../variables';
|
import { BrandName } from '../../../../variables';
|
||||||
|
|
||||||
// Setting BrandName to a variable here is necessary to get the jest tests
|
// Setting BrandName to a variable here is necessary to get the jest tests
|
||||||
@@ -84,7 +85,7 @@ const ManualSubForm = ({
|
|||||||
validated={!pathMeta.touched || !pathMeta.error ? 'default' : 'error'}
|
validated={!pathMeta.touched || !pathMeta.error ? 'default' : 'error'}
|
||||||
label={i18n._(t`Playbook Directory`)}
|
label={i18n._(t`Playbook Directory`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Select from the list of directories found in
|
content={i18n._(t`Select from the list of directories found in
|
||||||
the Project Base Path. Together the base path and the playbook
|
the Project Base Path. Together the base path and the playbook
|
||||||
directory provide the full path used to locate playbooks.`)}
|
directory provide the full path used to locate playbooks.`)}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { withI18n } from '@lingui/react';
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Detail } from '../../../components/DetailList';
|
import { Detail } from '../../../components/DetailList';
|
||||||
import { VariablesDetail } from '../../../components/CodeMirrorInput';
|
import { VariablesDetail } from '../../../components/CodeMirrorInput';
|
||||||
// import DetailPopover from '../../../components/DetailList/DetailPopover';
|
|
||||||
|
|
||||||
export default withI18n()(
|
export default withI18n()(
|
||||||
({ i18n, helpText, id, label, type, unit = '', value }) => {
|
({ i18n, helpText, id, label, type, unit = '', value }) => {
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import FormField, {
|
|||||||
CheckboxField,
|
CheckboxField,
|
||||||
PasswordField,
|
PasswordField,
|
||||||
FormSubmitError,
|
FormSubmitError,
|
||||||
FieldTooltip,
|
|
||||||
} from '../../../components/FormField';
|
} from '../../../components/FormField';
|
||||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import {
|
import {
|
||||||
required,
|
required,
|
||||||
noWhiteSpace,
|
noWhiteSpace,
|
||||||
@@ -30,7 +30,7 @@ function AnswerTypeField({ i18n }) {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={i18n._(t`Answer Type`)}
|
label={i18n._(t`Answer Type`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Choose an answer type or format you want as the prompt for the user.
|
t`Choose an answer type or format you want as the prompt for the user.
|
||||||
Refer to the Ansible Tower Documentation for more additional
|
Refer to the Ansible Tower Documentation for more additional
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import useRequest from '../../../util/useRequest';
|
|||||||
import FormActionGroup from '../../../components/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup';
|
||||||
import FormField, {
|
import FormField, {
|
||||||
CheckboxField,
|
CheckboxField,
|
||||||
FieldTooltip,
|
|
||||||
FormSubmitError,
|
FormSubmitError,
|
||||||
} from '../../../components/FormField';
|
} from '../../../components/FormField';
|
||||||
import FieldWithPrompt from '../../../components/FieldWithPrompt';
|
import FieldWithPrompt from '../../../components/FieldWithPrompt';
|
||||||
@@ -39,6 +38,7 @@ import {
|
|||||||
ProjectLookup,
|
ProjectLookup,
|
||||||
MultiCredentialsLookup,
|
MultiCredentialsLookup,
|
||||||
} from '../../../components/Lookup';
|
} from '../../../components/Lookup';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import { JobTemplatesAPI } from '../../../api';
|
import { JobTemplatesAPI } from '../../../api';
|
||||||
import LabelSelect from './LabelSelect';
|
import LabelSelect from './LabelSelect';
|
||||||
import PlaybookSelect from './PlaybookSelect';
|
import PlaybookSelect from './PlaybookSelect';
|
||||||
@@ -295,7 +295,7 @@ function JobTemplateForm({
|
|||||||
isRequired
|
isRequired
|
||||||
label={i18n._(t`Playbook`)}
|
label={i18n._(t`Playbook`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Select the playbook to be executed by this job.`
|
t`Select the playbook to be executed by this job.`
|
||||||
)}
|
)}
|
||||||
@@ -333,7 +333,7 @@ function JobTemplateForm({
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={i18n._(t`Labels`)}
|
label={i18n._(t`Labels`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Optional labels that describe this job template,
|
content={i18n._(t`Optional labels that describe this job template,
|
||||||
such as 'dev' or 'test'. Labels can be used to group and filter
|
such as 'dev' or 'test'. Labels can be used to group and filter
|
||||||
job templates and completed jobs.`)}
|
job templates and completed jobs.`)}
|
||||||
@@ -505,7 +505,7 @@ function JobTemplateForm({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Provisioning Callbacks`)}
|
{i18n._(t`Provisioning Callbacks`)}
|
||||||
|
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Enables creation of a provisioning
|
content={i18n._(t`Enables creation of a provisioning
|
||||||
callback URL. Using the URL a host can contact BRAND_NAME
|
callback URL. Using the URL a host can contact BRAND_NAME
|
||||||
and request a configuration update using this job
|
and request a configuration update using this job
|
||||||
@@ -525,7 +525,7 @@ function JobTemplateForm({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Enable Webhook`)}
|
{i18n._(t`Enable Webhook`)}
|
||||||
|
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Enable webhook for this template.`)}
|
content={i18n._(t`Enable webhook for this template.`)}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import useRequest from '../../../util/useRequest';
|
|||||||
import { FormColumnLayout } from '../../../components/FormLayout';
|
import { FormColumnLayout } from '../../../components/FormLayout';
|
||||||
import { CredentialLookup } from '../../../components/Lookup';
|
import { CredentialLookup } from '../../../components/Lookup';
|
||||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||||
import { FieldTooltip } from '../../../components/FormField';
|
import Popover from '../../../components/Popover';
|
||||||
import {
|
import {
|
||||||
JobTemplatesAPI,
|
JobTemplatesAPI,
|
||||||
WorkflowJobTemplatesAPI,
|
WorkflowJobTemplatesAPI,
|
||||||
@@ -129,9 +129,7 @@ function WebhookSubForm({ i18n, templateType }) {
|
|||||||
fieldId="webhook_service"
|
fieldId="webhook_service"
|
||||||
helperTextInvalid={webhookServiceMeta.error}
|
helperTextInvalid={webhookServiceMeta.error}
|
||||||
label={i18n._(t`Webhook Service`)}
|
label={i18n._(t`Webhook Service`)}
|
||||||
labelIcon={
|
labelIcon={<Popover content={i18n._(t`Select a webhook service.`)} />}
|
||||||
<FieldTooltip content={i18n._(t`Select a webhook service.`)} />
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
{...webhookServiceField}
|
{...webhookServiceField}
|
||||||
@@ -168,7 +166,7 @@ function WebhookSubForm({ i18n, templateType }) {
|
|||||||
fieldId="jt-webhookURL"
|
fieldId="jt-webhookURL"
|
||||||
label={i18n._(t`Webhook URL`)}
|
label={i18n._(t`Webhook URL`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Webhook services can launch jobs with this workflow job template by making a POST request to this URL.`
|
t`Webhook services can launch jobs with this workflow job template by making a POST request to this URL.`
|
||||||
)}
|
)}
|
||||||
@@ -186,7 +184,7 @@ function WebhookSubForm({ i18n, templateType }) {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={i18n._(t`Webhook Key`)}
|
label={i18n._(t`Webhook Key`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Webhook services can use this as a shared secret.`
|
t`Webhook services can use this as a shared secret.`
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -14,10 +14,7 @@ import {
|
|||||||
import { required } from '../../../util/validators';
|
import { required } from '../../../util/validators';
|
||||||
|
|
||||||
import FieldWithPrompt from '../../../components/FieldWithPrompt';
|
import FieldWithPrompt from '../../../components/FieldWithPrompt';
|
||||||
import FormField, {
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
FieldTooltip,
|
|
||||||
FormSubmitError,
|
|
||||||
} from '../../../components/FormField';
|
|
||||||
import {
|
import {
|
||||||
FormColumnLayout,
|
FormColumnLayout,
|
||||||
FormFullWidthLayout,
|
FormFullWidthLayout,
|
||||||
@@ -30,6 +27,7 @@ import { VariablesField } from '../../../components/CodeMirrorInput';
|
|||||||
import FormActionGroup from '../../../components/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup';
|
||||||
import ContentError from '../../../components/ContentError';
|
import ContentError from '../../../components/ContentError';
|
||||||
import CheckboxField from '../../../components/FormField/CheckboxField';
|
import CheckboxField from '../../../components/FormField/CheckboxField';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import LabelSelect from './LabelSelect';
|
import LabelSelect from './LabelSelect';
|
||||||
import WebhookSubForm from './WebhookSubForm';
|
import WebhookSubForm from './WebhookSubForm';
|
||||||
import { WorkFlowJobTemplate } from '../../../types';
|
import { WorkFlowJobTemplate } from '../../../types';
|
||||||
@@ -186,7 +184,7 @@ function WorkflowJobTemplateForm({
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={i18n._(t`Labels`)}
|
label={i18n._(t`Labels`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Optional labels that describe this job template,
|
content={i18n._(t`Optional labels that describe this job template,
|
||||||
such as 'dev' or 'test'. Labels can be used to group and filter
|
such as 'dev' or 'test'. Labels can be used to group and filter
|
||||||
job templates and completed jobs.`)}
|
job templates and completed jobs.`)}
|
||||||
@@ -221,7 +219,7 @@ function WorkflowJobTemplateForm({
|
|||||||
<span>
|
<span>
|
||||||
{i18n._(t`Enable Webhook`)}
|
{i18n._(t`Enable Webhook`)}
|
||||||
|
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Enable Webhook for this workflow job template.`
|
t`Enable Webhook for this workflow job template.`
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ import { Formik, useField } from 'formik';
|
|||||||
import { Form, FormGroup } from '@patternfly/react-core';
|
import { Form, FormGroup } from '@patternfly/react-core';
|
||||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||||
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||||
import FormField, {
|
import FormField, { FormSubmitError } from '../../../components/FormField';
|
||||||
FormSubmitError,
|
|
||||||
FieldTooltip,
|
|
||||||
} from '../../../components/FormField';
|
|
||||||
import ApplicationLookup from '../../../components/Lookup/ApplicationLookup';
|
import ApplicationLookup from '../../../components/Lookup/ApplicationLookup';
|
||||||
|
import Popover from '../../../components/Popover';
|
||||||
import { required } from '../../../util/validators';
|
import { required } from '../../../util/validators';
|
||||||
|
|
||||||
import { FormColumnLayout } from '../../../components/FormLayout';
|
import { FormColumnLayout } from '../../../components/FormLayout';
|
||||||
@@ -44,7 +42,7 @@ function UserTokenFormFields({ i18n }) {
|
|||||||
label={
|
label={
|
||||||
<span>
|
<span>
|
||||||
{i18n._(t`Application`)}
|
{i18n._(t`Application`)}
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(
|
content={i18n._(
|
||||||
t`Select the application that this token will belong to.`
|
t`Select the application that this token will belong to.`
|
||||||
)}
|
)}
|
||||||
@@ -69,7 +67,7 @@ function UserTokenFormFields({ i18n }) {
|
|||||||
validated={!scopeMeta.touched || !scopeMeta.error ? 'default' : 'error'}
|
validated={!scopeMeta.touched || !scopeMeta.error ? 'default' : 'error'}
|
||||||
label={i18n._(t`Scope`)}
|
label={i18n._(t`Scope`)}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<FieldTooltip
|
<Popover
|
||||||
content={i18n._(t`Specify a scope for the token's access`)}
|
content={i18n._(t`Specify a scope for the token's access`)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user