/* eslint-disable camelcase */ import React, { useState, useEffect, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Wizard } from '@patternfly/react-core'; import { get } from 'foremanReact/redux/API'; import history from 'foremanReact/history'; import { useForemanOrganization, useForemanLocation, } from 'foremanReact/Root/Context/ForemanContext'; import CategoryAndTemplate from './steps/CategoryAndTemplate/'; import { AdvancedFields } from './steps/AdvancedFields/AdvancedFields'; import { JOB_TEMPLATE, WIZARD_TITLES, initialScheduleState, } from './JobWizardConstants'; import { selectTemplateError, selectJobTemplate, selectIsSubmitting, } from './JobWizardSelectors'; import Schedule from './steps/Schedule/'; import HostsAndInputs from './steps/HostsAndInputs/'; import ReviewDetails from './steps/ReviewDetails/'; import { useValidation } from './validation'; import { useAutoFill } from './autofill'; import { submit } from './submit'; import './JobWizard.scss'; export const JobWizard = () => { const [jobTemplateID, setJobTemplateID] = useState(null); const [category, setCategory] = useState(''); const [advancedValues, setAdvancedValues] = useState({ templateValues: {} }); const [templateValues, setTemplateValues] = useState({}); // TODO use templateValues in advanced fields - description https://github.com/theforeman/foreman_remote_execution/pull/605 const [scheduleValue, setScheduleValue] = useState(initialScheduleState); const [selectedTargets, setSelectedTargets] = useState({ hosts: [], hostCollections: [], hostGroups: [], }); const [hostsSearchQuery, setHostsSearchQuery] = useState(''); const dispatch = useDispatch(); const setDefaults = useCallback( ({ data: { template_inputs, advanced_template_inputs, effective_user, job_template: { name, execution_timeout_interval, description_format }, }, }) => { const advancedTemplateValues = {}; const defaultTemplateValues = {}; const inputs = template_inputs; const advancedInputs = advanced_template_inputs; if (inputs) { setTemplateValues(() => { inputs.forEach(input => { defaultTemplateValues[input.name] = input?.default || ''; }); return defaultTemplateValues; }); } setAdvancedValues(currentAdvancedValues => { if (advancedInputs) { advancedInputs.forEach(input => { advancedTemplateValues[input.name] = input?.default || ''; }); } const generateDefaultDescription = () => { if (description_format) return description_format; const allInputs = [...advancedInputs, ...inputs]; if (!allInputs.length) return name; const inputsString = allInputs .map(({ name: inputname }) => `${inputname}="%{${inputname}}"`) .join(' '); return `${name} with inputs ${inputsString}`; }; return { ...currentAdvancedValues, effectiveUserValue: effective_user?.value || '', timeoutToKill: execution_timeout_interval || '', templateValues: advancedTemplateValues, description: generateDefaultDescription() || '', isRandomizedOrdering: false, }; }); }, [] ); useEffect(() => { if (jobTemplateID) { dispatch( get({ key: JOB_TEMPLATE, url: `/ui_job_wizard/template/${jobTemplateID}`, handleSuccess: setDefaults, }) ); } }, [jobTemplateID, setDefaults, dispatch]); const [valid, setValid] = useValidation({ advancedValues, templateValues, }); useAutoFill({ setSelectedTargets, setHostsSearchQuery, }); const templateError = !!useSelector(selectTemplateError); const templateResponse = useSelector(selectJobTemplate); const isSubmitting = useSelector(selectIsSubmitting); const isTemplate = !templateError && !!jobTemplateID && templateResponse.job_template; const steps = [ { name: WIZARD_TITLES.categoryAndTemplate, component: ( ), enableNext: isTemplate, }, { name: WIZARD_TITLES.hostsAndInputs, component: ( ), canJumpTo: isTemplate, enableNext: isTemplate && valid.hostsAndInputs, }, { name: WIZARD_TITLES.advanced, component: ( { setAdvancedValues(currentAdvancedValues => ({ ...currentAdvancedValues, ...newValues, })); }} templateValues={templateValues} /> ), canJumpTo: isTemplate && valid.hostsAndInputs, enableNext: isTemplate && valid.hostsAndInputs && valid.advanced, }, { name: WIZARD_TITLES.schedule, component: ( { setValid(currentValid => ({ ...currentValid, schedule: newValue })); }} /> ), canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced, enableNext: isTemplate && valid.hostsAndInputs && valid.advanced && valid.schedule, }, { name: WIZARD_TITLES.review, component: ( ), nextButtonText: 'Run', canJumpTo: isTemplate && valid.hostsAndInputs && valid.advanced && valid.schedule, enableNext: isTemplate && valid.hostsAndInputs && valid.advanced && valid.schedule && !isSubmitting, }, ]; const location = useForemanLocation(); const organization = useForemanOrganization(); return ( history.goBack()} navAriaLabel="Run Job steps" steps={steps} height="100%" className="job-wizard" onSave={() => { submit({ jobTemplateID, templateValues, advancedValues, scheduleValue, dispatch, selectedTargets, hostsSearchQuery, location, organization, }); }} /> ); }; export default JobWizard;