diff --git a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.ORIGINAL.jsx b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.ORIGINAL.jsx
new file mode 100644
index 0000000000..8666c838ea
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.ORIGINAL.jsx
@@ -0,0 +1,223 @@
+import React, { useState, useCallback, useEffect } from 'react';
+import { Wizard } from '@patternfly/react-core';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
+import { Formik } from 'formik';
+import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
+import useRequest from '@util/useRequest';
+import ContentError from '@components/ContentError';
+import ContentLoading from '@components/ContentLoading';
+import { required } from '@util/validators';
+import InventoryStep from './InventoryStep';
+import CredentialsStep from './CredentialsStep';
+import OtherPromptsStep from './OtherPromptsStep';
+import SurveyStep from './SurveyStep';
+import PreviewStep from './PreviewStep';
+import PromptFooter from './PromptFooter';
+import mergeExtraVars from './mergeExtraVars';
+
+const STEPS = {
+ INVENTORY: 'inventory',
+ CREDENTIALS: 'credentials',
+ PASSWORDS: 'passwords',
+ OTHER_PROMPTS: 'other',
+ SURVEY: 'survey',
+ PREVIEW: 'preview',
+};
+
+function showOtherPrompts(config) {
+ return (
+ config.ask_job_type_on_launch ||
+ config.ask_limit_on_launch ||
+ config.ask_verbosity_on_launch ||
+ config.ask_tags_on_launch ||
+ config.ask_skip_tags_on_launch ||
+ config.ask_variables_on_launch ||
+ config.ask_scm_branch_on_launch ||
+ config.ask_diff_mode_on_launch
+ );
+}
+
+function getInitialVisitedSteps(config) {
+ const visited = {};
+ if (config.ask_inventory_on_launch) {
+ visited[STEPS.INVENTORY] = false;
+ }
+ if (config.ask_credential_on_launch) {
+ visited[STEPS.CREDENTIALS] = false;
+ }
+ if (showOtherPrompts(config)) {
+ visited[STEPS.OTHER_PROMPTS] = false;
+ }
+ if (config.survey_enabled) {
+ visited[STEPS.SURVEY] = false;
+ }
+ return visited;
+}
+
+function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
+ const [formErrors, setFormErrors] = useState({});
+ const [visitedSteps, setVisitedSteps] = useState(
+ getInitialVisitedSteps(config)
+ );
+
+ const {
+ result: survey,
+ request: fetchSurvey,
+ error: surveyError,
+ } = useRequest(
+ useCallback(async () => {
+ if (!config.survey_enabled) {
+ return {};
+ }
+ const { data } =
+ resource.type === 'workflow_job_template'
+ ? await WorkflowJobTemplatesAPI.readSurvey(resource.id)
+ : await JobTemplatesAPI.readSurvey(resource.id);
+ return data;
+ }, [config.survey_enabled, resource])
+ );
+ useEffect(() => {
+ fetchSurvey();
+ }, [fetchSurvey]);
+
+ if (surveyError) {
+ return ;
+ }
+ if (config.survey_enabled && !survey) {
+ return ;
+ }
+
+ const steps = [];
+ const initialValues = {};
+ if (config.ask_inventory_on_launch) {
+ initialValues.inventory = resource?.summary_fields?.inventory || null;
+ steps.push({
+ id: STEPS.INVENTORY,
+ name: i18n._(t`Inventory`),
+ component: ,
+ });
+ }
+ if (config.ask_credential_on_launch) {
+ initialValues.credentials = resource?.summary_fields?.credentials || [];
+ steps.push({
+ id: STEPS.CREDENTIALS,
+ name: i18n._(t`Credentials`),
+ component: ,
+ });
+ }
+
+ // TODO: Add Credential Passwords step
+
+ if (config.ask_job_type_on_launch) {
+ initialValues.job_type = resource.job_type || '';
+ }
+ if (config.ask_limit_on_launch) {
+ initialValues.limit = resource.limit || '';
+ }
+ if (config.ask_verbosity_on_launch) {
+ initialValues.verbosity = resource.verbosity || 0;
+ }
+ if (config.ask_tags_on_launch) {
+ initialValues.job_tags = resource.job_tags || '';
+ }
+ if (config.ask_skip_tags_on_launch) {
+ initialValues.skip_tags = resource.skip_tags || '';
+ }
+ if (config.ask_variables_on_launch) {
+ initialValues.extra_vars = resource.extra_vars || '---';
+ }
+ if (config.ask_scm_branch_on_launch) {
+ initialValues.scm_branch = resource.scm_branch || '';
+ }
+ if (config.ask_diff_mode_on_launch) {
+ initialValues.diff_mode = resource.diff_mode || false;
+ }
+ if (showOtherPrompts(config)) {
+ steps.push({
+ id: STEPS.OTHER_PROMPTS,
+ name: i18n._(t`Other Prompts`),
+ component: ,
+ });
+ }
+ if (config.survey_enabled) {
+ initialValues.survey = {};
+ // survey.spec.forEach(question => {
+ // initialValues[`survey_${question.variable}`] = question.default;
+ // })
+ steps.push({
+ id: STEPS.SURVEY,
+ name: i18n._(t`Survey`),
+ component: ,
+ });
+ }
+ steps.push({
+ id: STEPS.PREVIEW,
+ name: i18n._(t`Preview`),
+ component: (
+
+ ),
+ enableNext: Object.keys(formErrors).length === 0,
+ nextButtonText: i18n._(t`Launch`),
+ });
+
+ const validate = values => {
+ // return {};
+ return { limit: ['required field'] };
+ };
+
+ const submit = values => {
+ const postValues = {};
+ const setValue = (key, value) => {
+ if (typeof value !== 'undefined' && value !== null) {
+ postValues[key] = value;
+ }
+ };
+ setValue('inventory_id', values.inventory?.id);
+ setValue('credentials', values.credentials?.map(c => c.id));
+ setValue('job_type', values.job_type);
+ setValue('limit', values.limit);
+ setValue('job_tags', values.job_tags);
+ setValue('skip_tags', values.skip_tags);
+ setValue('extra_vars', mergeExtraVars(values.extra_vars, values.survey));
+ onLaunch(postValues);
+ };
+ console.log('formErrors:', formErrors);
+
+ return (
+
+ {({ errors, values, touched, validateForm, handleSubmit }) => (
+ {
+ // console.log(`${prevStep.prevName} -> ${nextStep.name}`);
+ // console.log('errors', errors);
+ // console.log('values', values);
+ const newErrors = await validateForm();
+ setFormErrors(newErrors);
+ // console.log('new errors:', newErrors);
+ }}
+ onGoToStep={async (newStep, prevStep) => {
+ // console.log('errors', errors);
+ // console.log('values', values);
+ const newErrors = await validateForm();
+ setFormErrors(newErrors);
+ }}
+ title={i18n._(t`Prompts`)}
+ steps={steps}
+ // footer={}
+ />
+ )}
+
+ );
+}
+
+export { LaunchPrompt as _LaunchPrompt };
+export default withI18n()(LaunchPrompt);
diff --git a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx
index 8666c838ea..bc77a30555 100644
--- a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx
+++ b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx
@@ -3,174 +3,42 @@ import { Wizard } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Formik } from 'formik';
-import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
-import useRequest from '@util/useRequest';
+// import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
+// import useRequest from '@util/useRequest';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
-import { required } from '@util/validators';
-import InventoryStep from './InventoryStep';
-import CredentialsStep from './CredentialsStep';
-import OtherPromptsStep from './OtherPromptsStep';
-import SurveyStep from './SurveyStep';
-import PreviewStep from './PreviewStep';
-import PromptFooter from './PromptFooter';
+// import { required } from '@util/validators';
+// import InventoryStep from './InventoryStep';
+// import CredentialsStep from './CredentialsStep';
+// import OtherPromptsStep from './OtherPromptsStep';
+// import SurveyStep from './SurveyStep';
+// import PreviewStep from './PreviewStep';
+// import PromptFooter from './PromptFooter';
import mergeExtraVars from './mergeExtraVars';
-
-const STEPS = {
- INVENTORY: 'inventory',
- CREDENTIALS: 'credentials',
- PASSWORDS: 'passwords',
- OTHER_PROMPTS: 'other',
- SURVEY: 'survey',
- PREVIEW: 'preview',
-};
-
-function showOtherPrompts(config) {
- return (
- config.ask_job_type_on_launch ||
- config.ask_limit_on_launch ||
- config.ask_verbosity_on_launch ||
- config.ask_tags_on_launch ||
- config.ask_skip_tags_on_launch ||
- config.ask_variables_on_launch ||
- config.ask_scm_branch_on_launch ||
- config.ask_diff_mode_on_launch
- );
-}
-
-function getInitialVisitedSteps(config) {
- const visited = {};
- if (config.ask_inventory_on_launch) {
- visited[STEPS.INVENTORY] = false;
- }
- if (config.ask_credential_on_launch) {
- visited[STEPS.CREDENTIALS] = false;
- }
- if (showOtherPrompts(config)) {
- visited[STEPS.OTHER_PROMPTS] = false;
- }
- if (config.survey_enabled) {
- visited[STEPS.SURVEY] = false;
- }
- return visited;
-}
+import { useSteps, useVisitedSteps } from './hooks';
function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
- const [formErrors, setFormErrors] = useState({});
- const [visitedSteps, setVisitedSteps] = useState(
- getInitialVisitedSteps(config)
+ const { steps, initialValues, isReady, contentError } = useSteps(
+ config,
+ resource,
+ i18n
);
+ const [visitedSteps, visitStep] = useVisitedSteps(config);
- const {
- result: survey,
- request: fetchSurvey,
- error: surveyError,
- } = useRequest(
- useCallback(async () => {
- if (!config.survey_enabled) {
- return {};
- }
- const { data } =
- resource.type === 'workflow_job_template'
- ? await WorkflowJobTemplatesAPI.readSurvey(resource.id)
- : await JobTemplatesAPI.readSurvey(resource.id);
- return data;
- }, [config.survey_enabled, resource])
- );
- useEffect(() => {
- fetchSurvey();
- }, [fetchSurvey]);
-
- if (surveyError) {
- return ;
+ if (contentError) {
+ return ;
}
- if (config.survey_enabled && !survey) {
+ if (!isReady) {
return ;
}
- const steps = [];
- const initialValues = {};
- if (config.ask_inventory_on_launch) {
- initialValues.inventory = resource?.summary_fields?.inventory || null;
- steps.push({
- id: STEPS.INVENTORY,
- name: i18n._(t`Inventory`),
- component: ,
- });
- }
- if (config.ask_credential_on_launch) {
- initialValues.credentials = resource?.summary_fields?.credentials || [];
- steps.push({
- id: STEPS.CREDENTIALS,
- name: i18n._(t`Credentials`),
- component: ,
- });
- }
-
- // TODO: Add Credential Passwords step
-
- if (config.ask_job_type_on_launch) {
- initialValues.job_type = resource.job_type || '';
- }
- if (config.ask_limit_on_launch) {
- initialValues.limit = resource.limit || '';
- }
- if (config.ask_verbosity_on_launch) {
- initialValues.verbosity = resource.verbosity || 0;
- }
- if (config.ask_tags_on_launch) {
- initialValues.job_tags = resource.job_tags || '';
- }
- if (config.ask_skip_tags_on_launch) {
- initialValues.skip_tags = resource.skip_tags || '';
- }
- if (config.ask_variables_on_launch) {
- initialValues.extra_vars = resource.extra_vars || '---';
- }
- if (config.ask_scm_branch_on_launch) {
- initialValues.scm_branch = resource.scm_branch || '';
- }
- if (config.ask_diff_mode_on_launch) {
- initialValues.diff_mode = resource.diff_mode || false;
- }
- if (showOtherPrompts(config)) {
- steps.push({
- id: STEPS.OTHER_PROMPTS,
- name: i18n._(t`Other Prompts`),
- component: ,
- });
- }
- if (config.survey_enabled) {
- initialValues.survey = {};
- // survey.spec.forEach(question => {
- // initialValues[`survey_${question.variable}`] = question.default;
- // })
- steps.push({
- id: STEPS.SURVEY,
- name: i18n._(t`Survey`),
- component: ,
- });
- }
- steps.push({
- id: STEPS.PREVIEW,
- name: i18n._(t`Preview`),
- component: (
-
- ),
- enableNext: Object.keys(formErrors).length === 0,
- nextButtonText: i18n._(t`Launch`),
- });
-
+ // TODO move into hook?
const validate = values => {
// return {};
return { limit: ['required field'] };
};
+ // TODO move into hook?
const submit = values => {
const postValues = {};
const setValue = (key, value) => {
@@ -187,7 +55,6 @@ function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
setValue('extra_vars', mergeExtraVars(values.extra_vars, values.survey));
onLaunch(postValues);
};
- console.log('formErrors:', formErrors);
return (
@@ -197,22 +64,19 @@ function LaunchPrompt({ config, resource, onLaunch, onCancel, i18n }) {
onClose={onCancel}
onSave={handleSubmit}
onNext={async (nextStep, prevStep) => {
- // console.log(`${prevStep.prevName} -> ${nextStep.name}`);
- // console.log('errors', errors);
- // console.log('values', values);
+ console.log(prevStep);
+ visitStep(prevStep.id);
const newErrors = await validateForm();
- setFormErrors(newErrors);
- // console.log('new errors:', newErrors);
+ // updatePromptErrors(prevStep.prevName, newErrors);
}}
onGoToStep={async (newStep, prevStep) => {
- // console.log('errors', errors);
- // console.log('values', values);
+ console.log(prevStep);
+ visitStep(prevStep.id);
const newErrors = await validateForm();
- setFormErrors(newErrors);
+ // updatePromptErrors(prevStep.prevName, newErrors);
}}
title={i18n._(t`Prompts`)}
steps={steps}
- // footer={}
/>
)}
diff --git a/awx/ui_next/src/components/LaunchPrompt/hooks.js b/awx/ui_next/src/components/LaunchPrompt/hooks.js
new file mode 100644
index 0000000000..5248c588bc
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/hooks.js
@@ -0,0 +1,70 @@
+import { useState } from 'react';
+import useInventoryStep from './steps/useInventoryStep';
+import useCredentialsStep from './steps/useCredentialsStep';
+import useOtherPromptsStep from './steps/useOtherPromptsStep';
+import useSurveyStep from './steps/useSurveyStep';
+import usePreviewStep from './steps/usePreviewStep';
+
+// const INVENTORY = 'inventory';
+// const CREDENTIALS = 'credentials';
+// const PASSWORDS = 'passwords';
+// const OTHER_PROMPTS = 'other';
+// const SURVEY = 'survey';
+// const PREVIEW = 'preview';
+
+export function useSteps(config, resource, i18n) {
+ // TODO pass in form errors?
+ const formErrors = {};
+ const inventory = useInventoryStep(config, resource, i18n);
+ const credentials = useCredentialsStep(config, resource, i18n);
+ const otherPrompts = useOtherPromptsStep(config, resource, i18n);
+ const survey = useSurveyStep(config, resource, i18n);
+ const preview = usePreviewStep(
+ config,
+ resource,
+ survey.survey,
+ formErrors,
+ i18n
+ );
+
+ // TODO useState for steps to track dynamic steps (credentialPasswords)?
+ const steps = [
+ inventory.step,
+ credentials.step,
+ otherPrompts.step,
+ survey.step,
+ preview.step,
+ ].filter(step => step !== null);
+ const initialValues = {
+ ...inventory.initialValues,
+ ...credentials.initialValues,
+ ...otherPrompts.initialValues,
+ ...survey.initialValues,
+ };
+ const isReady =
+ inventory.isReady &&
+ credentials.isReady &&
+ otherPrompts.isReady &&
+ survey.isReady &&
+ preview.isReady;
+ const contentError =
+ inventory.error ||
+ credentials.error ||
+ otherPrompts.error ||
+ survey.error ||
+ preview.error;
+
+ return { steps, initialValues, isReady, contentError };
+}
+
+export function usePromptErrors(config) {
+ const [promptErrors, setPromptErrors] = useState({});
+ const updatePromptErrors = () => {};
+ return [promptErrors, updatePromptErrors];
+}
+
+// TODO this interrelates with usePromptErrors
+// merge? or pass result from one into the other?
+export function useVisitedSteps(config) {
+ return [[], () => {}];
+}
diff --git a/awx/ui_next/src/components/LaunchPrompt/CredentialsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/CredentialsStep.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/CredentialsStep.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/CredentialsStep.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/CredentialsStep.test.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/CredentialsStep.test.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/CredentialsStep.test.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/CredentialsStep.test.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/InventoryStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/InventoryStep.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/InventoryStep.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/InventoryStep.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/InventoryStep.test.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/InventoryStep.test.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/InventoryStep.test.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/InventoryStep.test.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.test.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.test.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/OtherPromptsStep.test.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.test.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/PreviewStep.jsx
similarity index 92%
rename from awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/PreviewStep.jsx
index 26d0572457..95e73509fb 100644
--- a/awx/ui_next/src/components/LaunchPrompt/PreviewStep.jsx
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/PreviewStep.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import { useFormikContext } from 'formik';
import yaml from 'js-yaml';
import PromptDetail from '@components/PromptDetail';
-import mergeExtraVars, { maskPasswords } from './mergeExtraVars';
+import mergeExtraVars, { maskPasswords } from '../mergeExtraVars';
function PreviewStep({ resource, config, survey, formErrors }) {
const { values } = useFormikContext();
diff --git a/awx/ui_next/src/components/LaunchPrompt/SurveyStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx
similarity index 100%
rename from awx/ui_next/src/components/LaunchPrompt/SurveyStep.jsx
rename to awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialsStep.jsx
new file mode 100644
index 0000000000..9fb9d88ecd
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialsStep.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { t } from '@lingui/macro';
+import CredentialsStep from './CredentialsStep';
+
+const STEP_ID = 'credentials';
+
+export default function useCredentialsStep(config, resource, i18n) {
+ return {
+ step: getStep(config, i18n),
+ initialValues: getInitialValues(config, resource),
+ isReady: true,
+ error: null,
+ };
+}
+
+function getStep(config, i18n) {
+ if (!config.ask_credential_on_launch) {
+ return null;
+ }
+ return {
+ id: STEP_ID,
+ name: i18n._(t`Credentials`),
+ component: ,
+ };
+}
+
+function getInitialValues(config, resource) {
+ if (!config.ask_credential_on_launch) {
+ return {};
+ }
+ return {
+ credentials: resource?.summary_fields?.credentials || [],
+ };
+}
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/useInventoryStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/useInventoryStep.jsx
new file mode 100644
index 0000000000..7aaed7d8e3
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/useInventoryStep.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { t } from '@lingui/macro';
+import InventoryStep from './InventoryStep';
+
+const STEP_ID = 'inventory';
+
+export default function useInventoryStep(config, resource, i18n) {
+ return {
+ step: getStep(config, i18n),
+ initialValues: getInitialValues(config, resource),
+ isReady: true,
+ error: null,
+ };
+}
+
+function getStep(config, i18n) {
+ if (!config.ask_inventory_on_launch) {
+ return null;
+ }
+ return {
+ id: STEP_ID,
+ name: i18n._(t`Inventory`),
+ component: ,
+ };
+}
+
+function getInitialValues(config, resource) {
+ if (!config.ask_inventory_on_launch) {
+ return {};
+ }
+ return {
+ inventory: resource?.summary_fields?.inventory || null,
+ };
+}
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/useOtherPromptsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/useOtherPromptsStep.jsx
new file mode 100644
index 0000000000..7b5f5d2cce
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/useOtherPromptsStep.jsx
@@ -0,0 +1,67 @@
+import React from 'react';
+import { t } from '@lingui/macro';
+import OtherPromptsStep from './OtherPromptsStep';
+
+const STEP_ID = 'other';
+
+export default function useOtherPrompt(config, resource, i18n) {
+ return {
+ step: getStep(config, i18n),
+ initialValues: getInitialValues(config, resource),
+ isReady: true,
+ error: null,
+ };
+}
+
+function getStep(config, i18n) {
+ if (!shouldShowPrompt(config)) {
+ return null;
+ }
+ return {
+ id: STEP_ID,
+ name: i18n._(t`Other Prompts`),
+ component: ,
+ };
+}
+
+function shouldShowPrompt(config) {
+ return (
+ config.ask_job_type_on_launch ||
+ config.ask_limit_on_launch ||
+ config.ask_verbosity_on_launch ||
+ config.ask_tags_on_launch ||
+ config.ask_skip_tags_on_launch ||
+ config.ask_variables_on_launch ||
+ config.ask_scm_branch_on_launch ||
+ config.ask_diff_mode_on_launch
+ );
+}
+
+function getInitialValues(config, resource) {
+ const initialValues = {};
+ if (config.ask_job_type_on_launch) {
+ initialValues.job_type = resource.job_type || '';
+ }
+ if (config.ask_limit_on_launch) {
+ initialValues.limit = resource.limit || '';
+ }
+ if (config.ask_verbosity_on_launch) {
+ initialValues.verbosity = resource.verbosity || 0;
+ }
+ if (config.ask_tags_on_launch) {
+ initialValues.job_tags = resource.job_tags || '';
+ }
+ if (config.ask_skip_tags_on_launch) {
+ initialValues.skip_tags = resource.skip_tags || '';
+ }
+ if (config.ask_variables_on_launch) {
+ initialValues.extra_vars = resource.extra_vars || '---';
+ }
+ if (config.ask_scm_branch_on_launch) {
+ initialValues.scm_branch = resource.scm_branch || '';
+ }
+ if (config.ask_diff_mode_on_launch) {
+ initialValues.diff_mode = resource.diff_mode || false;
+ }
+ return initialValues;
+}
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/usePreviewStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/usePreviewStep.jsx
new file mode 100644
index 0000000000..ec34d8e7d5
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/usePreviewStep.jsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { t } from '@lingui/macro';
+import PreviewStep from './PreviewStep';
+
+const STEP_ID = 'preview';
+
+export default function usePreviewStep(
+ config,
+ resource,
+ survey,
+ formErrors,
+ i18n
+) {
+ return {
+ step: {
+ id: STEP_ID,
+ name: i18n._(t`Preview`),
+ component: (
+
+ ),
+ enableNext: Object.keys(formErrors).length === 0,
+ nextButtonText: i18n._(t`Launch`),
+ },
+ initialValues: {},
+ isReady: true,
+ error: null,
+ };
+}
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/useSurveyStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/useSurveyStep.jsx
new file mode 100644
index 0000000000..5383e629ba
--- /dev/null
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/useSurveyStep.jsx
@@ -0,0 +1,60 @@
+import React, { useEffect, useCallback } from 'react';
+import { t } from '@lingui/macro';
+import useRequest from '@util/useRequest';
+import { JobTemplatesAPI, WorkflowJobTemplatesAPI } from '@api';
+import SurveyStep from './SurveyStep';
+
+const STEP_ID = 'survey';
+
+export default function useSurveyStep(config, resource, i18n) {
+ const { result: survey, request: fetchSurvey, isLoading, error } = useRequest(
+ useCallback(async () => {
+ if (!config.survey_enabled) {
+ return {};
+ }
+ const { data } =
+ resource.type === 'workflow_job_template'
+ ? await WorkflowJobTemplatesAPI.readSurvey(resource.id)
+ : await JobTemplatesAPI.readSurvey(resource.id);
+ return data;
+ }, [config.survey_enabled, resource])
+ );
+
+ useEffect(() => {
+ fetchSurvey();
+ }, [fetchSurvey]);
+
+ return {
+ step: getStep(config, survey, i18n),
+ initialValues: getInitialValues(config, survey),
+ survey,
+ isReady: !isLoading && !!survey,
+ error,
+ };
+}
+
+function getStep(config, survey, i18n) {
+ if (!config.survey_enabled) {
+ return null;
+ }
+ return {
+ id: STEP_ID,
+ name: i18n._(t`Survey`),
+ component: ,
+ };
+}
+
+function getInitialValues(config, survey) {
+ if (!config.survey_enabled || !survey) {
+ return {};
+ }
+ const values = {};
+ survey.spec.forEach(question => {
+ if (question.type === 'multiselect') {
+ values[`survey_${question.variable}`] = question.default.split('\n');
+ } else {
+ values[`survey_${question.variable}`] = question.default;
+ }
+ });
+ return values;
+}