diff --git a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx
index 94955e78f5..ef5f8e32f8 100644
--- a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx
+++ b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx
@@ -1,5 +1,5 @@
-import React, { Component, Fragment } from 'react';
-import { Link, withRouter } from 'react-router-dom';
+import React, { Fragment, useState, useEffect } from 'react';
+import { Link, useParams } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import {
Button,
@@ -13,10 +13,10 @@ import { t } from '@lingui/macro';
import { CardBody, CardActionsRow } from '@components/Card';
import ContentError from '@components/ContentError';
-import LaunchButton from '@components/LaunchButton';
import ContentLoading from '@components/ContentLoading';
import { ChipGroup, Chip, CredentialChip } from '@components/Chip';
import { DetailList, Detail, UserDateDetail } from '@components/DetailList';
+import LaunchButton from '@components/LaunchButton';
import { JobTemplatesAPI } from '@api';
const MissingDetail = styled(Detail)`
@@ -25,319 +25,290 @@ const MissingDetail = styled(Detail)`
}
`;
-class JobTemplateDetail extends Component {
- constructor(props) {
- super(props);
- this.state = {
- contentError: null,
- hasContentLoading: true,
- instanceGroups: [],
- };
- this.readInstanceGroups = this.readInstanceGroups.bind(this);
- }
+function JobTemplateDetail({ i18n, template }) {
+ const {
+ ask_inventory_on_launch,
+ allow_simultaneous,
+ become_enabled,
+ created,
+ description,
+ diff_mode,
+ forks,
+ host_config_key,
+ job_slice_count,
+ job_tags,
+ job_type,
+ name,
+ limit,
+ modified,
+ playbook,
+ skip_tags,
+ timeout,
+ summary_fields,
+ use_fact_cache,
+ url,
+ verbosity,
+ } = template;
+ const [contentError, setContentError] = useState(null);
+ const [hasContentLoading, setHasContentLoading] = useState(false);
+ const [instanceGroups, setInstanceGroups] = useState([]);
+ const { id: templateId } = useParams();
- componentDidMount() {
- this.readInstanceGroups();
- }
+ useEffect(() => {
+ (async () => {
+ setContentError(null);
+ setHasContentLoading(true);
+ try {
+ const {
+ data: { results = [] },
+ } = await JobTemplatesAPI.readInstanceGroups(templateId);
+ setInstanceGroups(results);
+ } catch (error) {
+ setContentError(error);
+ } finally {
+ setHasContentLoading(false);
+ }
+ })();
+ }, [templateId]);
- async readInstanceGroups() {
- const { match } = this.props;
- try {
- const { data } = await JobTemplatesAPI.readInstanceGroups(
- match.params.id
- );
- this.setState({ instanceGroups: [...data.results] });
- } catch (err) {
- this.setState({ contentError: err });
- } finally {
- this.setState({ hasContentLoading: false });
- }
- }
+ const canLaunch =
+ summary_fields.user_capabilities && summary_fields.user_capabilities.start;
+ const verbosityOptions = [
+ { verbosity: 0, details: i18n._(t`0 (Normal)`) },
+ { verbosity: 1, details: i18n._(t`1 (Verbose)`) },
+ { verbosity: 2, details: i18n._(t`2 (More Verbose)`) },
+ { verbosity: 3, details: i18n._(t`3 (Debug)`) },
+ { verbosity: 4, details: i18n._(t`4 (Connection Debug)`) },
+ { verbosity: 5, details: i18n._(t`5 (WinRM Debug)`) },
+ ];
+ const verbosityDetails = verbosityOptions.filter(
+ option => option.verbosity === verbosity
+ );
+ const generateCallBackUrl = `${window.location.origin + url}callback/`;
+ const renderOptionsField =
+ become_enabled || host_config_key || allow_simultaneous || use_fact_cache;
- render() {
- const {
- template: {
- ask_inventory_on_launch,
- allow_simultaneous,
- become_enabled,
- created,
- description,
- diff_mode,
- forks,
- host_config_key,
- job_slice_count,
- job_tags,
- job_type,
- name,
- limit,
- modified,
- playbook,
- skip_tags,
- timeout,
- summary_fields,
- use_fact_cache,
- url,
- verbosity,
- },
- hasTemplateLoading,
- template,
- i18n,
- match,
- } = this.props;
- const canLaunch = summary_fields.user_capabilities.start;
- const { instanceGroups, hasContentLoading, contentError } = this.state;
- const verbosityOptions = [
- { verbosity: 0, details: i18n._(t`0 (Normal)`) },
- { verbosity: 1, details: i18n._(t`1 (Verbose)`) },
- { verbosity: 2, details: i18n._(t`2 (More Verbose)`) },
- { verbosity: 3, details: i18n._(t`3 (Debug)`) },
- { verbosity: 4, details: i18n._(t`4 (Connection Debug)`) },
- { verbosity: 5, details: i18n._(t`5 (WinRM Debug)`) },
- ];
- const verbosityDetails = verbosityOptions.filter(
- option => option.verbosity === verbosity
- );
- const generateCallBackUrl = `${window.location.origin + url}callback/`;
- const isInitialized = !hasTemplateLoading && !hasContentLoading;
+ const renderOptions = (
+
+ {become_enabled && (
+
+ {i18n._(t`Enable Privilege Escalation`)}
+
+ )}
+ {host_config_key && (
+
+ {i18n._(t`Allow Provisioning Callbacks`)}
+
+ )}
+ {allow_simultaneous && (
+
+ {i18n._(t`Enable Concurrent Jobs`)}
+
+ )}
+ {use_fact_cache && (
+
+ {i18n._(t`Use Fact Cache`)}
+
+ )}
+
+ );
- const renderOptionsField =
- become_enabled || host_config_key || allow_simultaneous || use_fact_cache;
+ const renderMissingDataDetail = value => (
+
+ );
- const renderOptions = (
-
- {become_enabled && (
-
- {i18n._(t`Enable Privilege Escalation`)}
-
- )}
- {host_config_key && (
-
- {i18n._(t`Allow Provisioning Callbacks`)}
-
- )}
- {allow_simultaneous && (
-
- {i18n._(t`Enable Concurrent Jobs`)}
-
- )}
- {use_fact_cache && (
-
- {i18n._(t`Use Fact Cache`)}
-
- )}
-
- );
+ const inventoryValue = (kind, id) => {
+ const inventorykind = kind === 'smart' ? 'smart_inventory' : 'inventory';
- const renderMissingDataDetail = value => (
-
- );
-
- const inventoryValue = (kind, id) => {
- const inventorykind =
- kind === 'smart' ? (kind = 'smart_inventory') : (kind = 'inventory');
-
- return ask_inventory_on_launch ? (
-
-
- {summary_fields.inventory.name}
-
- {i18n._(t`(Prompt on Launch)`)}
-
- ) : (
+ return ask_inventory_on_launch ? (
+
{summary_fields.inventory.name}
- );
- };
+ {i18n._(t`(Prompt on Launch)`)}
+
+ ) : (
+
+ {summary_fields.inventory.name}
+
+ );
+ };
- if (contentError) {
- return ;
- }
+ if (contentError) {
+ return ;
+ }
- if (hasContentLoading) {
- return ;
- }
+ if (hasContentLoading) {
+ return ;
+ }
- return (
- isInitialized && (
-
-
-
-
-
-
- {summary_fields.inventory ? (
-
- ) : (
- !ask_inventory_on_launch &&
- renderMissingDataDetail(i18n._(t`Inventory`))
+ return (
+
+
+
+
+
+ {summary_fields.inventory ? (
+
- {summary_fields.project
- ? summary_fields.project.name
- : i18n._(t`Deleted`)}
-
- }
- />
- ) : (
- renderMissingDataDetail(i18n._(t`Project`))
- )}
-
-
-
-
+ />
+ ) : (
+ !ask_inventory_on_launch &&
+ renderMissingDataDetail(i18n._(t`Inventory`))
+ )}
+ {summary_fields.project ? (
+
+ {summary_fields.project.name}
+
+ }
+ />
+ ) : (
+ renderMissingDataDetail(i18n._(t`Project`))
+ )}
+
+
+
+
+
+
+
+
+
+
+ {host_config_key && (
+
-
-
-
-
- {host_config_key && (
-
-
-
-
- )}
- {renderOptionsField && (
-
- )}
- {summary_fields.credentials &&
- summary_fields.credentials.length > 0 && (
-
- {summary_fields.credentials.map(c => (
-
- ))}
-
- }
- />
- )}
- {summary_fields.labels && summary_fields.labels.results.length > 0 && (
-
- {summary_fields.labels.results.map(l => (
-
- {l.name}
-
- ))}
-
- }
- />
- )}
- {instanceGroups.length > 0 && (
-
- {instanceGroups.map(ig => (
-
- {ig.name}
-
- ))}
-
- }
- />
- )}
- {job_tags && job_tags.length > 0 && (
-
- {job_tags.split(',').map(jobTag => (
-
- {jobTag}
-
- ))}
-
- }
- />
- )}
- {skip_tags && skip_tags.length > 0 && (
-
- {skip_tags.split(',').map(skipTag => (
-
- {skipTag}
-
- ))}
-
- }
- />
- )}
-
-
- {summary_fields.user_capabilities.edit && (
-
+
+ {summary_fields.user_capabilities &&
+ summary_fields.user_capabilities.edit && (
+
+ )}
+ {canLaunch && (
+
+ {({ handleLaunch }) => (
+
)}
- {canLaunch && (
-
- {({ handleLaunch }) => (
-
- )}
-
- )}
-
-
- )
- );
- }
+
+ )}
+
+
+ );
}
+
export { JobTemplateDetail as _JobTemplateDetail };
-export default withI18n()(withRouter(JobTemplateDetail));
+export default withI18n()(JobTemplateDetail);