diff --git a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
index 1238665601..bd8abe0849 100644
--- a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
+++ b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
@@ -22,6 +22,8 @@ import {
} from '@patternfly/react-icons';
import { WorkflowApprovalsAPI } from '../../api';
import useRequest from '../../util/useRequest';
+import getDocsBaseUrl from '../../util/getDocsBaseUrl';
+import { useConfig } from '../../contexts/Config';
import useWsPendingApprovalCount from './useWsPendingApprovalCount';
const PendingWorkflowApprovals = styled.div`
@@ -35,9 +37,6 @@ const PendingWorkflowApprovalBadge = styled(Badge)`
margin-left: 10px;
`;
-const DOCLINK =
- 'https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html';
-
function PageHeaderToolbar({
isAboutDisabled,
onAboutClick,
@@ -47,6 +46,7 @@ function PageHeaderToolbar({
}) {
const [isHelpOpen, setIsHelpOpen] = useState(false);
const [isUserOpen, setIsUserOpen] = useState(false);
+ const config = useConfig();
const {
request: fetchPendingApprovalCount,
@@ -101,37 +101,39 @@ function PageHeaderToolbar({
- {i18n._(t`Info`)}}>
-
-
-
-
- }
- dropdownItems={[
-
- {i18n._(t`Help`)}
- ,
-
- {i18n._(t`About`)}
- ,
- ]}
- />
-
-
+
+
+
+
+ }
+ dropdownItems={[
+
+ {i18n._(t`Help`)}
+ ,
+
+ {i18n._(t`About`)}
+ ,
+ ]}
+ />
+
{i18n._(t`User`)}}>
{
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const AzureSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const AzureSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ 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';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/EC2SubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/EC2SubForm.jsx
index d4f41879ba..c5a988fa3d 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/EC2SubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/EC2SubForm.jsx
@@ -11,10 +11,13 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const EC2SubForm = ({ i18n }) => {
const { setFieldValue } = useFormikContext();
const [credentialField] = useField('credential');
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -23,8 +26,9 @@ const EC2SubForm = ({ i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ 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';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/GCESubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/GCESubForm.jsx
index eee39c1d93..793211107a 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/GCESubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/GCESubForm.jsx
@@ -12,6 +12,8 @@ import {
SourceVarsField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const GCESubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const GCESubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const GCESubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ 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';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/OpenStackSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/OpenStackSubForm.jsx
index 7404bfea6e..3d85189b10 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/OpenStackSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/OpenStackSubForm.jsx
@@ -12,6 +12,8 @@ import {
HostFilterField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const OpenStackSubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const OpenStackSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const OpenStackSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ const pluginLink = `${getDocsBaseUrl(
+ config
+ )}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/openstack/cloud/openstack_inventory.html';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SatelliteSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SatelliteSubForm.jsx
index 90dd5e8e0d..0d27c3b298 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SatelliteSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SatelliteSubForm.jsx
@@ -12,6 +12,8 @@ import {
HostFilterField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const SatelliteSubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const SatelliteSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const SatelliteSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ const pluginLink = `${getDocsBaseUrl(
+ config
+ )}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/theforeman/foreman/foreman_inventory.html';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/TowerSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/TowerSubForm.jsx
index 7898e05400..dd3f57df41 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/TowerSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/TowerSubForm.jsx
@@ -12,6 +12,8 @@ import {
SourceVarsField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const TowerSubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const TowerSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const TowerSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ const pluginLink = `${getDocsBaseUrl(
+ config
+ )}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/awx/awx/tower_inventory.html';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VMwareSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VMwareSubForm.jsx
index 89025d5fd3..f9b0b16eb4 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VMwareSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VMwareSubForm.jsx
@@ -12,6 +12,8 @@ import {
HostFilterField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const VMwareSubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const VMwareSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const VMwareSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ const pluginLink = `${getDocsBaseUrl(
+ config
+ )}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_vm_inventory_inventory.html';
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VirtualizationSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VirtualizationSubForm.jsx
index d338d1554a..e081d9f629 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VirtualizationSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/VirtualizationSubForm.jsx
@@ -12,6 +12,8 @@ import {
SourceVarsField,
} from './SharedFields';
import { required } from '../../../../util/validators';
+import getDocsBaseUrl from '../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../contexts/Config';
const VirtualizationSubForm = ({ autoPopulateCredential, i18n }) => {
const { setFieldValue } = useFormikContext();
@@ -19,6 +21,7 @@ const VirtualizationSubForm = ({ autoPopulateCredential, i18n }) => {
name: 'credential',
validate: required(i18n._(t`Select a value for this field`), i18n),
});
+ const config = useConfig();
const handleCredentialUpdate = useCallback(
value => {
@@ -27,8 +30,9 @@ const VirtualizationSubForm = ({ autoPopulateCredential, i18n }) => {
[setFieldValue]
);
- const pluginLink =
- 'http://docs.ansible.com/ansible-tower/latest/html/userguide/inventories.html#inventory-plugins';
+ const pluginLink = `${getDocsBaseUrl(
+ config
+ )}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/ovirt/ovirt/ovirt_inventory.html';
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
index 8478305ed4..3ae4894e85 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
@@ -26,6 +26,8 @@ import JobTemplatesList from './JobTemplatesList';
import ProjectsList from './ProjectsList';
import WorkflowJobTemplatesList from './WorkflowJobTemplatesList';
import FormField from '../../../../../../components/FormField';
+import getDocsBaseUrl from '../../../../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../../../../contexts/Config';
const NodeTypeErrorAlert = styled(Alert)`
margin-bottom: 20px;
@@ -59,6 +61,7 @@ function NodeTypeStep({ i18n }) {
const [convergenceField, , convergenceFieldHelpers] = useField('convergence');
const [isConvergenceOpen, setIsConvergenceOpen] = useState(false);
+ const config = useConfig();
const isValid = !approvalNameMeta.touched || !approvalNameMeta.error;
return (
@@ -212,7 +215,9 @@ function NodeTypeStep({ i18n }) {
t`Preconditions for running this node when there are multiple parents. Refer to the`
)}{' '}
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
index 48b616656c..c0c18e2ab7 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
@@ -23,6 +23,8 @@ import {
WorkflowDispatchContext,
WorkflowStateContext,
} from '../../../contexts/Workflow';
+import getDocsBaseUrl from '../../../util/getDocsBaseUrl';
+import { useConfig } from '../../../contexts/Config';
const Badge = styled(PFBadge)`
align-items: center;
@@ -47,9 +49,6 @@ const ActionButton = styled(Button)`
`;
ActionButton.displayName = 'ActionButton';
-const DOCLINK =
- 'https://docs.ansible.com/ansible-tower/latest/html/userguide/workflow_templates.html#ug-wf-editor';
-
function VisualizerToolbar({
i18n,
onClose,
@@ -59,8 +58,8 @@ function VisualizerToolbar({
readOnly,
}) {
const dispatch = useContext(WorkflowDispatchContext);
-
const { nodes, showLegend, showTools } = useContext(WorkflowStateContext);
+ const config = useConfig();
const totalNodes = nodes.reduce((n, node) => n + !node.isDeleted, 0) - 1;
@@ -113,7 +112,9 @@ function VisualizerToolbar({
variant="plain"
component="a"
target="_blank"
- href={DOCLINK}
+ href={`${getDocsBaseUrl(
+ config
+ )}/html/userguide/workflow_templates.html#ug-wf-editor`}
>