Adds popover text for Inventory and InventorySources

This commit is contained in:
Alex Corey
2022-05-09 10:40:36 -04:00
parent f7be6b6423
commit 33df2e8aa4
16 changed files with 336 additions and 417 deletions

View File

@@ -154,7 +154,7 @@ VariablesDetail.propTypes = {
label: node.isRequired, label: node.isRequired,
rows: oneOfType([number, string]), rows: oneOfType([number, string]),
dataCy: string, dataCy: string,
helpText: string, helpText: oneOfType([node, string]),
name: string.isRequired, name: string.isRequired,
}; };
VariablesDetail.defaultProps = { VariablesDetail.defaultProps = {

View File

@@ -16,10 +16,10 @@ import { InventoriesAPI } from 'api';
import useRequest, { useDismissableError } from 'hooks/useRequest'; import useRequest, { useDismissableError } from 'hooks/useRequest';
import { Inventory } from 'types'; import { Inventory } from 'types';
import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails'; import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails';
import helpText from '../shared/Inventory.helptext';
function InventoryDetail({ inventory }) { function InventoryDetail({ inventory }) {
const history = useHistory(); const history = useHistory();
const { const {
result: instanceGroups, result: instanceGroups,
isLoading, isLoading,
@@ -106,6 +106,7 @@ function InventoryDetail({ inventory }) {
inventory.summary_fields.labels?.results?.length > 0 && ( inventory.summary_fields.labels?.results?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
helpText={helpText.labels}
label={t`Labels`} label={t`Labels`}
value={ value={
<ChipGroup <ChipGroup
@@ -123,6 +124,7 @@ function InventoryDetail({ inventory }) {
)} )}
<VariablesDetail <VariablesDetail
label={t`Variables`} label={t`Variables`}
helpText={helpText.variables()}
value={inventory.variables} value={inventory.variables}
rows={4} rows={4}
name="variables" name="variables"

View File

@@ -9,6 +9,8 @@ import {
TextListItemVariants, TextListItemVariants,
Tooltip, Tooltip,
} from '@patternfly/react-core'; } from '@patternfly/react-core';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import AlertModal from 'components/AlertModal'; import AlertModal from 'components/AlertModal';
import ContentError from 'components/ContentError'; import ContentError from 'components/ContentError';
import ContentLoading from 'components/ContentLoading'; import ContentLoading from 'components/ContentLoading';
@@ -26,8 +28,10 @@ import { InventorySourcesAPI } from 'api';
import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails'; import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails';
import useIsMounted from 'hooks/useIsMounted'; import useIsMounted from 'hooks/useIsMounted';
import { formatDateString } from 'util/dates'; import { formatDateString } from 'util/dates';
import Popover from 'components/Popover';
import InventorySourceSyncButton from '../shared/InventorySourceSyncButton'; import InventorySourceSyncButton from '../shared/InventorySourceSyncButton';
import useWsInventorySourcesDetails from '../InventorySources/useWsInventorySourcesDetails'; import useWsInventorySourcesDetails from '../InventorySources/useWsInventorySourcesDetails';
import helpText from '../shared/Inventory.helptext';
function InventorySourceDetail({ inventorySource }) { function InventorySourceDetail({ inventorySource }) {
const { const {
@@ -64,6 +68,7 @@ function InventorySourceDetail({ inventorySource }) {
} = summary_fields; } = summary_fields;
const [deletionError, setDeletionError] = useState(false); const [deletionError, setDeletionError] = useState(false);
const config = useConfig();
const history = useHistory(); const history = useHistory();
const isMounted = useIsMounted(); const isMounted = useIsMounted();
@@ -82,6 +87,7 @@ function InventorySourceDetail({ inventorySource }) {
{} {}
); );
const docsBaseUrl = getDocsBaseUrl(config);
useEffect(() => { useEffect(() => {
fetchSourceChoices(); fetchSourceChoices();
}, [fetchSourceChoices]); }, [fetchSourceChoices]);
@@ -123,21 +129,33 @@ function InventorySourceDetail({ inventorySource }) {
{overwrite && ( {overwrite && (
<TextListItem component={TextListItemVariants.li}> <TextListItem component={TextListItemVariants.li}>
{t`Overwrite local groups and hosts from remote inventory source`} {t`Overwrite local groups and hosts from remote inventory source`}
<Popover content={helpText.subFormOptions.overwrite} />
</TextListItem> </TextListItem>
)} )}
{overwrite_vars && ( {overwrite_vars && (
<TextListItem component={TextListItemVariants.li}> <TextListItem component={TextListItemVariants.li}>
{t`Overwrite local variables from remote inventory source`} {t`Overwrite local variables from remote inventory source`}
<Popover content={helpText.subFormOptions.overwriteVariables} />
</TextListItem> </TextListItem>
)} )}
{update_on_launch && ( {update_on_launch && (
<TextListItem component={TextListItemVariants.li}> <TextListItem component={TextListItemVariants.li}>
{t`Update on launch`} {t`Update on launch`}
<Popover
content={helpText.subFormOptions.updateOnLaunch({
value: source_project,
})}
/>
</TextListItem> </TextListItem>
)} )}
{update_on_project_update && ( {update_on_project_update && (
<TextListItem component={TextListItemVariants.li}> <TextListItem component={TextListItemVariants.li}>
{t`Update on project update`} {t`Update on project update`}
<Popover
content={helpText.subFormOptions.updateOnProjectUpdate({
value: source_project,
})}
/>
</TextListItem> </TextListItem>
)} )}
</TextList> </TextList>
@@ -226,17 +244,35 @@ function InventorySourceDetail({ inventorySource }) {
{source === 'scm' ? ( {source === 'scm' ? (
<Detail <Detail
label={t`Inventory file`} label={t`Inventory file`}
helpText={helpText.sourcePath}
value={source_path === '' ? t`/ (project root)` : source_path} value={source_path === '' ? t`/ (project root)` : source_path}
/> />
) : null} ) : null}
<Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} /> <Detail
label={t`Verbosity`}
helpText={helpText.subFormVerbosityFields}
value={VERBOSITY[verbosity]}
/>
<Detail <Detail
label={t`Cache timeout`} label={t`Cache timeout`}
value={`${update_cache_timeout} ${t`seconds`}`} value={`${update_cache_timeout} ${t`seconds`}`}
helpText={helpText.subFormOptions.cachedTimeOut}
/>
<Detail
label={t`Host Filter`}
helpText={helpText.hostFilter}
value={host_filter}
/>
<Detail
label={t`Enabled Variable`}
helpText={helpText.enabledVariableField}
value={enabled_var}
/>
<Detail
label={t`Enabled Value`}
helpText={helpText.enabledValue}
value={enabled_value}
/> />
<Detail label={t`Host Filter`} value={host_filter} />
<Detail label={t`Enabled Variable`} value={enabled_var} />
<Detail label={t`Enabled Value`} value={enabled_value} />
{credentials?.length > 0 && ( {credentials?.length > 0 && (
<Detail <Detail
fullWidth fullWidth
@@ -254,6 +290,7 @@ function InventorySourceDetail({ inventorySource }) {
label={t`Source variables`} label={t`Source variables`}
rows={4} rows={4}
value={source_vars} value={source_vars}
helpText={helpText.sourceVars(docsBaseUrl, source)}
name="source_vars" name="source_vars"
dataCy="inventory-source-detail-variables" dataCy="inventory-source-detail-variables"
/> />

View File

@@ -0,0 +1,196 @@
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { t, Trans } from '@lingui/macro';
import { Link } from 'react-router-dom';
const ansibleDocUrls = {
ec2: 'https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html',
azure_rm:
'https://docs.ansible.com/ansible/latest/collections/azure/azcollection/azure_rm_inventory.html',
controller:
'https://docs.ansible.com/ansible/latest/collections/awx/awx/tower_inventory.html',
gce: 'https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_compute_inventory.html',
insights:
'https://docs.ansible.com/ansible/latest/collections/redhatinsights/insights/insights_inventory.html',
openstack:
'https://docs.ansible.com/ansible/latest/collections/openstack/cloud/openstack_inventory.html',
satellite6:
'https://docs.ansible.com/ansible/latest/collections/theforeman/foreman/foreman_inventory.html',
rhv: 'https://docs.ansible.com/ansible/latest/collections/ovirt/ovirt/ovirt_inventory.html',
vmware:
'https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_vm_inventory_inventory.html',
};
const getInventoryHelpTextStrings = {
labels: t`Optional labels that describe this inventory,
such as 'dev' or 'test'. Labels can be used to group and filter
inventories and completed jobs.`,
variables: () => {
const jsonExample = `
{
"somevar": "somevalue"
"somepassword": "Magic"
}
`;
const yamlExample = `
---
somevar: somevalue
somepassword: magic
`;
return (
<>
<Trans>
Variables must be in JSON or YAML syntax. Use the radio button to
toggle between the two.
</Trans>
<br />
<br />
<Trans>JSON:</Trans>
<pre>{jsonExample}</pre>
<br />
<Trans>YAML:</Trans>
<pre>{yamlExample}</pre>
<br />
<Trans>
View JSON examples at{' '}
<a
href="http://www.json.org"
target="_blank"
rel="noopener noreferrer"
>
www.json.org
</a>
</Trans>
<br />
<Trans>
View YAML examples at{' '}
<a
href="http://docs.ansible.com/YAMLSyntax.html"
target="_blank"
rel="noopener noreferrer"
>
docs.ansible.com
</a>
</Trans>
</>
);
},
subFormVerbosityFields: t`Control the level of output Ansible
will produce for inventory source update jobs.`,
subFormOptions: {
overwrite: (
<>
{t`If checked, any hosts and groups that were
previously present on the external source but are now removed
will be removed from the inventory. Hosts and groups
that were not managed by the inventory source will be promoted
to the next manually created group or if there is no manually
created group to promote them into, they will be left in the "all"
default group for the inventory.`}
<br />
<br />
{t`When not checked, local child
hosts and groups not found on the external source will remain
untouched by the inventory update process.`}
</>
),
overwriteVariables: (
<>
{t`If checked, all variables for child groups
and hosts will be removed and replaced by those found
on the external source.`}
<br />
<br />
{t`When not checked, a merge will be performed,
combining local variables with those found on the
external source.`}
</>
),
updateOnLaunch: ({ value }) => (
<>
<div>
{t`Each time a job runs using this inventory,
refresh the inventory from the selected source before
executing job tasks.`}
</div>
<br />
{value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${value.id}/details`}> {value.name} </Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
),
updateOnProjectUpdate: ({ value }) => (
<>
<div>
{t`After every project update where the SCM revision
changes, refresh the inventory from the selected source
before executing job tasks. This is intended for static content,
like the Ansible inventory .ini file format.`}
</div>
<br />
{value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${value.id}/details`}> {value.name} </Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
),
cachedTimeOut: t`Time in seconds to consider an inventory sync
to be current. During job runs and callbacks the task system will
evaluate the timestamp of the latest sync. If it is older than
Cache Timeout, it is not considered current, and a new
inventory sync will be performed.`,
},
enabledVariableField: t`Retrieve the enabled state from the given dict of host variables.
The enabled variable may be specified using dot notation, e.g: 'foo.bar'`,
enabledValue: t`This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import.`,
hostFilter: t`Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied.`,
sourceVars: (docsBaseUrl, source) => {
const docsUrl = `${docsBaseUrl}/html/userguide/inventories.html#inventory-plugins`;
let sourceType = '';
if (source && source !== 'scm') {
const type = ansibleDocUrls[source].split(/[/,.]/);
sourceType = type[type.length - 2];
}
return (
<>
<Trans>
Variables used to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a
href={docsBaseUrl ? docsUrl : ''}
target="_blank"
rel="noopener noreferrer"
>
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a
href={ansibleDocUrls[source]}
target="_blank"
rel="noopener noreferrer"
>
{sourceType}
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
);
},
sourcePath: t`The inventory file
to be synced by this source. You can select from
the dropdown or enter a file within the input.`,
};
export default getInventoryHelpTextStrings;

View File

@@ -13,6 +13,7 @@ import InstanceGroupsLookup from 'components/Lookup/InstanceGroupsLookup';
import OrganizationLookup from 'components/Lookup/OrganizationLookup'; import OrganizationLookup from 'components/Lookup/OrganizationLookup';
import ContentError from 'components/ContentError'; import ContentError from 'components/ContentError';
import { FormColumnLayout, FormFullWidthLayout } from 'components/FormLayout'; import { FormColumnLayout, FormFullWidthLayout } from 'components/FormLayout';
import helpText from './Inventory.helptext';
function InventoryFormFields({ inventory }) { function InventoryFormFields({ inventory }) {
const [contentError, setContentError] = useState(false); const [contentError, setContentError] = useState(false);
@@ -72,13 +73,7 @@ function InventoryFormFields({ inventory }) {
<FormFullWidthLayout> <FormFullWidthLayout>
<FormGroup <FormGroup
label={t`Labels`} label={t`Labels`}
labelIcon={ labelIcon={<Popover content={helpText.labels} />}
<Popover
content={t`Optional labels that describe this inventory,
such as 'dev' or 'test'. Labels can be used to group and filter
inventories and completed jobs.`}
/>
}
fieldId="inventory-labels" fieldId="inventory-labels"
> >
<LabelSelect <LabelSelect
@@ -89,7 +84,7 @@ function InventoryFormFields({ inventory }) {
/> />
</FormGroup> </FormGroup>
<VariablesField <VariablesField
tooltip={t`Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax`} tooltip={helpText.variables()}
id="inventory-variables" id="inventory-variables"
name="variables" name="variables"
label={t`Variables`} label={t`Variables`}

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl'; import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config'; import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { import {
OptionsField, OptionsField,
SourceVarsField, SourceVarsField,
@@ -13,6 +13,7 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const AzureSubForm = ({ autoPopulateCredential }) => { const AzureSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
@@ -27,12 +28,7 @@ const AzureSubForm = ({ autoPopulateCredential }) => {
}, },
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const docsBaseUrl = getDocsBaseUrl(config);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/azure/azcollection/azure_rm_inventory.html';
return ( return (
<> <>
@@ -54,24 +50,7 @@ const AzureSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'azure_rm')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
azure_rm
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,11 +1,11 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl'; import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config'; import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { import {
OptionsField, OptionsField,
VerbosityField, VerbosityField,
@@ -14,13 +14,13 @@ import {
HostFilterField, HostFilterField,
SourceVarsField, SourceVarsField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const ControllerSubForm = ({ autoPopulateCredential }) => { const ControllerSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] = const [credentialField, credentialMeta, credentialHelpers] =
useField('credential'); useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -29,12 +29,6 @@ const ControllerSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/awx/awx/tower_inventory.html';
return ( return (
<> <>
<CredentialLookup <CredentialLookup
@@ -55,24 +49,10 @@ const ControllerSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(
<> getDocsBaseUrl(config),
<Trans> 'controller'
Enter variables to configure the inventory source. For a detailed )}
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
Tower
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,9 +1,9 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import getDocsBaseUrl from 'util/getDocsBaseUrl'; import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config'; import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { import {
OptionsField, OptionsField,
SourceVarsField, SourceVarsField,
@@ -12,12 +12,12 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const EC2SubForm = () => { const EC2SubForm = () => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta] = useField('credential'); const [credentialField, credentialMeta] = useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -25,12 +25,7 @@ const EC2SubForm = () => {
}, },
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const docsBaseUrl = getDocsBaseUrl(config);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html';
return ( return (
<> <>
@@ -48,24 +43,7 @@ const EC2SubForm = () => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'ec2')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
aws_ec2
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl'; import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config'; import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { import {
OptionsField, OptionsField,
VerbosityField, VerbosityField,
@@ -13,13 +13,13 @@ import {
HostFilterField, HostFilterField,
SourceVarsField, SourceVarsField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const GCESubForm = ({ autoPopulateCredential }) => { const GCESubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] = const [credentialField, credentialMeta, credentialHelpers] =
useField('credential'); useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -27,12 +27,7 @@ const GCESubForm = ({ autoPopulateCredential }) => {
}, },
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const docsBaseUrl = getDocsBaseUrl(config);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_compute_inventory.html';
return ( return (
<> <>
@@ -54,24 +49,7 @@ const GCESubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'gce')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
gcp_compute
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,11 +1,11 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl'; import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config'; import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { import {
OptionsField, OptionsField,
VerbosityField, VerbosityField,
@@ -14,13 +14,13 @@ import {
HostFilterField, HostFilterField,
SourceVarsField, SourceVarsField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const InsightsSubForm = ({ autoPopulateCredential }) => { const InsightsSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] = const [credentialField, credentialMeta, credentialHelpers] =
useField('credential'); useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -28,12 +28,7 @@ const InsightsSubForm = ({ autoPopulateCredential }) => {
}, },
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const docsBaseUrl = getDocsBaseUrl(config);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/redhatinsights/insights/insights_inventory.html';
return ( return (
<> <>
@@ -55,24 +50,7 @@ const InsightsSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'insights')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
Insights
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup'; import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators'; import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import { import {
OptionsField, OptionsField,
SourceVarsField, SourceVarsField,
@@ -13,6 +13,7 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const OpenStackSubForm = ({ autoPopulateCredential }) => { const OpenStackSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
@@ -28,12 +29,6 @@ const OpenStackSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/openstack/cloud/openstack_inventory.html';
return ( return (
<> <>
<CredentialLookup <CredentialLookup
@@ -54,24 +49,10 @@ const OpenStackSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(
<> getDocsBaseUrl(config),
<Trans> 'openstack'
Enter variables to configure the inventory source. For a detailed )}
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
openstack
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -21,12 +21,14 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const SCMSubForm = ({ autoPopulateProject }) => { const SCMSubForm = ({ autoPopulateProject }) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [sourcePath, setSourcePath] = useState([]); const [sourcePath, setSourcePath] = useState([]);
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField] = useField('credential'); const [credentialField] = useField('credential');
const [projectField, projectMeta, projectHelpers] = const [projectField, projectMeta, projectHelpers] =
useField('source_project'); useField('source_project');
const [sourcePathField, sourcePathMeta, sourcePathHelpers] = useField({ const [sourcePathField, sourcePathMeta, sourcePathHelpers] = useField({
@@ -104,13 +106,7 @@ const SCMSubForm = ({ autoPopulateProject }) => {
} }
isRequired isRequired
label={t`Inventory file`} label={t`Inventory file`}
labelIcon={ labelIcon={<Popover content={helpText.sourcePath} />}
<Popover
content={t`Select the inventory file
to be synced by this source. You can select from
the dropdown or enter a file within the input.`}
/>
}
> >
<Select <Select
ouiaId="InventorySourceForm-source_path" ouiaId="InventorySourceForm-source_path"

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup'; import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators'; import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import { import {
OptionsField, OptionsField,
SourceVarsField, SourceVarsField,
@@ -13,13 +13,13 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const SatelliteSubForm = ({ autoPopulateCredential }) => { const SatelliteSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] = const [credentialField, credentialMeta, credentialHelpers] =
useField('credential'); useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -28,12 +28,6 @@ const SatelliteSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/theforeman/foreman/foreman_inventory.html';
return ( return (
<> <>
<CredentialLookup <CredentialLookup
@@ -54,24 +48,10 @@ const SatelliteSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(
<> getDocsBaseUrl(config),
<Trans> 'satellite6'
Enter variables to configure the inventory source. For a detailed )}
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
foreman
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,8 +1,7 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useField } from 'formik'; import { useField } from 'formik';
import { Link } from 'react-router-dom';
import { FormGroup } from '@patternfly/react-core'; 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';
@@ -10,67 +9,23 @@ import { VariablesField } from 'components/CodeEditor';
import FormField, { CheckboxField } from 'components/FormField'; import FormField, { CheckboxField } from 'components/FormField';
import { FormFullWidthLayout, FormCheckboxLayout } from 'components/FormLayout'; import { FormFullWidthLayout, FormCheckboxLayout } from 'components/FormLayout';
import Popover from 'components/Popover'; import Popover from 'components/Popover';
import helpText from '../Inventory.helptext';
export const SourceVarsField = ({ popoverContent }) => { export const SourceVarsField = ({ popoverContent }) => (
const jsonExample = ` <FormFullWidthLayout>
{ <VariablesField
"somevar": "somevalue" id="source_vars"
"somepassword": "Magic" name="source_vars"
} label={t`Source variables`}
`; tooltip={
const yamlExample = ` <>
--- {popoverContent}
somevar: somevalue {helpText.variables()}
somepassword: magic </>
`; }
return ( />
<FormFullWidthLayout> </FormFullWidthLayout>
<VariablesField );
id="source_vars"
name="source_vars"
label={t`Source variables`}
tooltip={
<div>
{popoverContent}
<Trans>
Enter variables using either JSON or YAML syntax. Use the radio
button to toggle between the two.
</Trans>
<br />
<br />
<Trans>JSON:</Trans>
<pre>{jsonExample}</pre>
<br />
<Trans>YAML:</Trans>
<pre>{yamlExample}</pre>
<br />
<Trans>
View JSON examples at{' '}
<a
href="http://www.json.org"
target="_blank"
rel="noopener noreferrer"
>
www.json.org
</a>
</Trans>
<br />
<Trans>
View YAML examples at{' '}
<a
href="http://docs.ansible.com/YAMLSyntax.html"
target="_blank"
rel="noopener noreferrer"
>
docs.ansible.com
</a>
</Trans>
</div>
}
/>
</FormFullWidthLayout>
);
};
export const VerbosityField = () => { export const VerbosityField = () => {
const [field, meta, helpers] = useField('verbosity'); const [field, meta, helpers] = useField('verbosity');
@@ -80,17 +35,13 @@ export const VerbosityField = () => {
{ value: '1', key: '1', label: t`1 (Info)` }, { value: '1', key: '1', label: t`1 (Info)` },
{ value: '2', key: '2', label: t`2 (Debug)` }, { value: '2', key: '2', label: t`2 (Debug)` },
]; ];
return ( return (
<FormGroup <FormGroup
fieldId="verbosity" fieldId="verbosity"
validated={isValid ? 'default' : 'error'} validated={isValid ? 'default' : 'error'}
label={t`Verbosity`} label={t`Verbosity`}
labelIcon={ labelIcon={<Popover content={helpText.subFormVerbosityFields} />}
<Popover
content={t`Control the level of output Ansible
will produce for inventory source update jobs.`}
/>
}
> >
<AnsibleSelect <AnsibleSelect
id="verbosity" id="verbosity"
@@ -105,8 +56,8 @@ export const VerbosityField = () => {
export const OptionsField = ({ showProjectUpdate = false }) => { export const OptionsField = ({ showProjectUpdate = false }) => {
const [updateOnLaunchField] = useField('update_on_launch'); const [updateOnLaunchField] = useField('update_on_launch');
const [, , updateCacheTimeoutHelper] = useField('update_cache_timeout'); const [, , updateCacheTimeoutHelper] = useField('update_cache_timeout');
const [updatedOnProjectUpdateField] = useField('update_on_project_update');
const [projectField] = useField('source_project'); const [projectField] = useField('source_project');
const [updatedOnProjectUpdateField] = useField('update_on_project_update');
useEffect(() => { useEffect(() => {
if (!updateOnLaunchField.value) { if (!updateOnLaunchField.value) {
@@ -123,66 +74,20 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
id="overwrite" id="overwrite"
name="overwrite" name="overwrite"
label={t`Overwrite`} label={t`Overwrite`}
tooltip={ tooltip={helpText.subFormOptions.overwrite}
<>
{t`If checked, any hosts and groups that were
previously present on the external source but are now removed
will be removed from the inventory. Hosts and groups
that were not managed by the inventory source will be promoted
to the next manually created group or if there is no manually
created group to promote them into, they will be left in the "all"
default group for the inventory.`}
<br />
<br />
{t`When not checked, local child
hosts and groups not found on the external source will remain
untouched by the inventory update process.`}
</>
}
/> />
<CheckboxField <CheckboxField
id="overwrite_vars" id="overwrite_vars"
name="overwrite_vars" name="overwrite_vars"
label={t`Overwrite variables`} label={t`Overwrite variables`}
tooltip={ tooltip={helpText.subFormOptions.overwriteVariables}
<>
{t`If checked, all variables for child groups
and hosts will be removed and replaced by those found
on the external source.`}
<br />
<br />
{t`When not checked, a merge will be performed,
combining local variables with those found on the
external source.`}
</>
}
/> />
<CheckboxField <CheckboxField
isDisabled={updatedOnProjectUpdateField.value} isDisabled={updatedOnProjectUpdateField.value}
id="update_on_launch" id="update_on_launch"
name="update_on_launch" name="update_on_launch"
label={t`Update on launch`} label={t`Update on launch`}
tooltip={ tooltip={helpText.subFormOptions.updateOnLaunch(projectField)}
<>
<div>
{t`Each time a job runs using this inventory,
refresh the inventory from the selected source before
executing job tasks.`}
</div>
<br />
{projectField?.value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${projectField.value.id}/details`}>
{' '}
{projectField.value.name}{' '}
</Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
}
/> />
{showProjectUpdate && ( {showProjectUpdate && (
<CheckboxField <CheckboxField
@@ -190,28 +95,9 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
id="update_on_project_update" id="update_on_project_update"
name="update_on_project_update" name="update_on_project_update"
label={t`Update on project update`} label={t`Update on project update`}
tooltip={ tooltip={helpText.subFormOptions.updateOnProjectUpdate(
<> projectField
<div> )}
{t`After every project update where the SCM revision
changes, refresh the inventory from the selected source
before executing job tasks. This is intended for static content,
like the Ansible inventory .ini file format.`}
</div>
<br />
{projectField?.value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${projectField.value.id}/details`}>
{' '}
{projectField.value.name}{' '}
</Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
}
/> />
)} )}
</FormCheckboxLayout> </FormCheckboxLayout>
@@ -226,11 +112,7 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
max="2147483647" max="2147483647"
validate={minMaxValue(0, 2147483647)} validate={minMaxValue(0, 2147483647)}
label={t`Cache timeout (seconds)`} label={t`Cache timeout (seconds)`}
tooltip={t`Time in seconds to consider an inventory sync tooltip={helpText.cachedTimeOut}
to be current. During job runs and callbacks the task system will
evaluate the timestamp of the latest sync. If it is older than
Cache Timeout, it is not considered current, and a new
inventory sync will be performed.`}
/> />
)} )}
</> </>
@@ -241,8 +123,7 @@ export const EnabledVarField = () => (
<FormField <FormField
id="inventory-enabled-var" id="inventory-enabled-var"
label={t`Enabled Variable`} label={t`Enabled Variable`}
tooltip={t`Retrieve the enabled state from the given dict of host variables. tooltip={helpText.enabledVariableField}
The enabled variable may be specified using dot notation, e.g: 'foo.bar'`}
name="enabled_var" name="enabled_var"
type="text" type="text"
/> />
@@ -252,7 +133,7 @@ export const EnabledValueField = () => (
<FormField <FormField
id="inventory-enabled-value" id="inventory-enabled-value"
label={t`Enabled Value`} label={t`Enabled Value`}
tooltip={t`This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import.`} tooltip={helpText.enabledValue}
name="enabled_value" name="enabled_value"
type="text" type="text"
/> />
@@ -262,7 +143,7 @@ export const HostFilterField = () => (
<FormField <FormField
id="host-filter" id="host-filter"
label={t`Host Filter`} label={t`Host Filter`}
tooltip={t`Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied.`} tooltip={helpText.hostFilter}
name="host_filter" name="host_filter"
type="text" type="text"
validate={regExp()} validate={regExp()}

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup'; import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators'; import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import { import {
OptionsField, OptionsField,
SourceVarsField, SourceVarsField,
@@ -13,13 +13,13 @@ import {
EnabledValueField, EnabledValueField,
HostFilterField, HostFilterField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const VMwareSubForm = ({ autoPopulateCredential }) => { const VMwareSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] = const [credentialField, credentialMeta, credentialHelpers] =
useField('credential'); useField('credential');
const config = useConfig(); const config = useConfig();
const handleCredentialUpdate = useCallback( const handleCredentialUpdate = useCallback(
(value) => { (value) => {
setFieldValue('credential', value); setFieldValue('credential', value);
@@ -28,11 +28,7 @@ const VMwareSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const pluginLink = `${getDocsBaseUrl( const docsBaseUrl = getDocsBaseUrl(config);
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_vm_inventory_inventory.html';
return ( return (
<> <>
@@ -54,24 +50,7 @@ const VMwareSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'vmware')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
vmware_vm_inventory
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );

View File

@@ -1,10 +1,10 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik'; import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup'; import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators'; import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import { import {
OptionsField, OptionsField,
VerbosityField, VerbosityField,
@@ -13,6 +13,7 @@ import {
HostFilterField, HostFilterField,
SourceVarsField, SourceVarsField,
} from './SharedFields'; } from './SharedFields';
import helpText from '../Inventory.helptext';
const VirtualizationSubForm = ({ autoPopulateCredential }) => { const VirtualizationSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext(); const { setFieldValue, setFieldTouched } = useFormikContext();
@@ -28,12 +29,7 @@ const VirtualizationSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched] [setFieldValue, setFieldTouched]
); );
const pluginLink = `${getDocsBaseUrl( const docsBaseUrl = getDocsBaseUrl(config);
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/ovirt/ovirt/ovirt_inventory.html';
return ( return (
<> <>
<CredentialLookup <CredentialLookup
@@ -54,24 +50,7 @@ const VirtualizationSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField /> <EnabledValueField />
<OptionsField /> <OptionsField />
<SourceVarsField <SourceVarsField
popoverContent={ popoverContent={helpText.sourceVars(docsBaseUrl, 'rhv')}
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
ovirt
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
/> />
</> </>
); );