import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { Modal, Button, Alert, Checkbox, TextContent, Text, TextVariants } from '@patternfly/react-core';
import { translate as __ } from 'foremanReact/common/I18n';
import { STATUS } from 'foremanReact/constants';
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
import { useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
import { selectAPIStatus } from 'foremanReact/redux/API/APISelectors';
import EnvironmentPaths from '../../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths';
import { ENVIRONMENT_PATHS_KEY } from '../../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathConstants';
import api from '../../../../../services/api';
import getContentViews from '../../../../../scenes/ContentViews/ContentViewsActions';
import { selectContentViews, selectContentViewStatus } from '../../../../../scenes/ContentViews/ContentViewSelectors';
import updateHostContentViewAndEnvironment, { runSubmanRepos } from './HostContentViewActions';
import HOST_CV_AND_ENV_KEY from './HostContentViewConstants';
import { getHostDetails } from '../../HostDetailsActions';
import ContentViewSelect from '../../../../../scenes/ContentViews/components/ContentViewSelect/ContentViewSelect';
import ContentViewSelectOption
from '../../../../../scenes/ContentViews/components/ContentViewSelect/ContentViewSelectOption';
import { getCVPlaceholderText } from '../../../../../scenes/ContentViews/components/ContentViewSelect/helpers';
import { useRexJobPolling } from '../../Tabs/RemoteExecutionHooks';
import './ChangeHostCVModal.scss';
import { selectEnvironmentPaths } from '../../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathSelectors';
const ENV_PATH_OPTIONS = { key: ENVIRONMENT_PATHS_KEY };
const ChangeHostCVModal = ({
isOpen,
closeModal,
hostEnvId,
orgId,
hostId,
contentSourceId,
hostName,
multiEnv,
}) => {
const { content_view_assignment: initialCVModalOpen } = useUrlParams();
const [selectedEnvForHost, setSelectedEnvForHost]
= useState([]);
const [selectedCVForHost, setSelectedCVForHost] = useState(null);
const [cvSelectOpen, setCVSelectOpen] = useState(false);
const [forceProfileUpload, setForceProfileUpload] = useState(false);
const dispatch = useDispatch();
const contentViewsInEnvResponse = useSelector(state => selectContentViews(state, `FOR_ENV_${hostEnvId}`));
const environmentPathResponse = useSelector(selectEnvironmentPaths);
const environments = environmentPathResponse?.results?.map(path => path.environments).flat();
const { results } = contentViewsInEnvResponse;
const contentViewsInEnvStatus = useSelector(state => selectContentViewStatus(state, `FOR_ENV_${hostEnvId}`));
const hostUpdateStatus = useSelector(state => selectAPIStatus(state, HOST_CV_AND_ENV_KEY));
const pathsUrl = `/organizations/${orgId}/environments/paths?permission_type=promotable${contentSourceId ? `&content_source_id=${contentSourceId}` : ''}`;
useAPI( // No TableWrapper here, so we can useAPI from Foreman
'get',
api.getApiUrl(pathsUrl),
ENV_PATH_OPTIONS,
);
const selectedCVForHostId = results?.find(cv => cv.name === selectedCVForHost)?.id;
const handleModalClose = () => {
setCVSelectOpen(false);
setForceProfileUpload(false);
setSelectedCVForHost(null);
setSelectedEnvForHost([]);
closeModal();
};
const handleCancel = () => {
handleModalClose();
if (initialCVModalOpen) {
window.history.back();
}
};
const selectedEnv = selectedEnvForHost?.[0];
const selectedEnvId = selectedEnv?.id;
const handleCVSelect = (event, selection) => {
setSelectedCVForHost(selection);
setCVSelectOpen(false);
};
const handleEnvSelect = (selection) => {
dispatch(getContentViews({
environment_id: selection[0].id,
include_default: true,
full_result: true,
order: 'default DESC', // show Default Organization View first
}, `FOR_ENV_${hostEnvId}`));
setSelectedCVForHost(null);
setSelectedEnvForHost(selection);
};
const { results: contentViewsInEnv = [] } = contentViewsInEnvResponse;
const canSave = !!(selectedCVForHost && selectedEnvForHost.length);
const { triggerJobStart } =
useRexJobPolling(runSubmanRepos, () => getHostDetails({ hostname: hostName }));
const refreshHostDetails = () => {
if (forceProfileUpload) {
triggerJobStart(hostName);
}
handleModalClose();
return dispatch(getHostDetails({ hostname: hostName }));
};
const handleSave = () => {
const requestBody = {
id: hostId,
host: {
content_facet_attributes: {
content_view_id: selectedCVForHostId,
lifecycle_environment_id: selectedEnvId,
},
},
};
dispatch(updateHostContentViewAndEnvironment(
requestBody, hostId,
refreshHostDetails, handleModalClose,
));
};
const cvPlaceholderText = getCVPlaceholderText({
environments: selectedEnvForHost,
cvSelectOptions: contentViewsInEnv,
contentViewsStatus: contentViewsInEnvStatus,
});
const stillLoading =
(contentViewsInEnvStatus === STATUS.PENDING || hostUpdateStatus === STATUS.PENDING);
const noContentViewsAvailable =
(contentViewsInEnv.length === 0 || selectedEnvForHost.length === 0);
const modalActions = ([
,
,
]);
return (
{contentViewsInEnvStatus === STATUS.RESOLVED &&
!!selectedEnvForHost.length && contentViewsInEnv.length === 0 &&
{__('View the Content Views page')}
{__(' to manage and promote content views, or select a different environment.')}
}
{environments?.some(env => env?.content_source?.environment_is_associated === false) &&
{__('To enable them, add the environment to the host\'s content source, or ')}
{__('change the host\'s content source.')}
}
{multiEnv &&
}
setSelectedCVForHost(null)}
onSelect={handleCVSelect}
isOpen={cvSelectOpen}
isDisabled={stillLoading || noContentViewsAvailable}
onToggle={isExpanded => setCVSelectOpen(isExpanded)}
placeholderText={cvPlaceholderText}
>
{(contentViewsInEnv.length !== 0 && selectedEnvForHost.length !== 0) &&
contentViewsInEnv?.map(cv => (
))}
{forceProfileUpload ? __('Errata and package information will be updated immediately.') : __('Errata and package information will be updated at the next host check-in or package action.')}
);
};
ChangeHostCVModal.propTypes = {
isOpen: PropTypes.bool,
closeModal: PropTypes.func,
hostEnvId: PropTypes.number,
orgId: PropTypes.number.isRequired,
hostId: PropTypes.number.isRequired,
contentSourceId: PropTypes.number,
hostName: PropTypes.string.isRequired,
multiEnv: PropTypes.bool,
};
ChangeHostCVModal.defaultProps = {
isOpen: false,
closeModal: () => {},
hostEnvId: null,
contentSourceId: null,
multiEnv: false,
};
export default ChangeHostCVModal;