import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { Container, Button, Layout, StatefulButton, TransitionReplace, } from '@openedx/paragon'; import { CheckCircle, Info, Warning } from '@openedx/paragon/icons'; import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import Placeholder from '../editors/Placeholder'; import AlertProctoringError from '../generic/AlertProctoringError'; import { useModel } from '../generic/model-store'; import InternetConnectionAlert from '../generic/internet-connection-alert'; import { parseArrayOrObjectValues } from '../utils'; import { RequestStatus } from '../data/constants'; import SubHeader from '../generic/sub-header/SubHeader'; import AlertMessage from '../generic/alert-message'; import { fetchCourseAppSettings, updateCourseAppSetting, fetchProctoringExamErrors } from './data/thunks'; import { getCourseAppSettings, getSavingStatus, getProctoringExamErrors, getSendRequestErrors, getLoadingStatus, } from './data/selectors'; import SettingCard from './setting-card/SettingCard'; import SettingsSidebar from './settings-sidebar/SettingsSidebar'; import validateAdvancedSettingsData from './utils'; import messages from './messages'; import ModalError from './modal-error/ModalError'; import getPageHeadTitle from '../generic/utils'; const AdvancedSettings = ({ courseId }) => { const intl = useIntl(); const dispatch = useDispatch(); const [saveSettingsPrompt, showSaveSettingsPrompt] = useState(false); const [showDeprecated, setShowDeprecated] = useState(false); const [errorModal, showErrorModal] = useState(false); const [editedSettings, setEditedSettings] = useState({}); const [errorFields, setErrorFields] = useState([]); const [showSuccessAlert, setShowSuccessAlert] = useState(false); const [isQueryPending, setIsQueryPending] = useState(false); const [isEditableState, setIsEditableState] = useState(false); const [hasInternetConnectionError, setInternetConnectionError] = useState(false); const courseDetails = useModel('courseDetails', courseId); document.title = getPageHeadTitle(courseDetails?.name, intl.formatMessage(messages.headingTitle)); useEffect(() => { dispatch(fetchCourseAppSettings(courseId)); dispatch(fetchProctoringExamErrors(courseId)); }, [courseId]); const advancedSettingsData = useSelector(getCourseAppSettings); const savingStatus = useSelector(getSavingStatus); const proctoringExamErrors = useSelector(getProctoringExamErrors); const settingsWithSendErrors = useSelector(getSendRequestErrors) || {}; const loadingSettingsStatus = useSelector(getLoadingStatus); const isLoading = loadingSettingsStatus === RequestStatus.IN_PROGRESS; const updateSettingsButtonState = { labels: { default: intl.formatMessage(messages.buttonSaveText), pending: intl.formatMessage(messages.buttonSavingText), }, disabledStates: ['pending'], }; const { proctoringErrors, mfeProctoredExamSettingsUrl, } = proctoringExamErrors; useEffect(() => { if (savingStatus === RequestStatus.SUCCESSFUL) { setIsQueryPending(false); setShowSuccessAlert(true); setIsEditableState(false); setTimeout(() => setShowSuccessAlert(false), 15000); window.scrollTo({ top: 0, behavior: 'smooth' }); showSaveSettingsPrompt(false); } else if (savingStatus === RequestStatus.FAILED && !hasInternetConnectionError) { setErrorFields(settingsWithSendErrors); showErrorModal(true); } }, [savingStatus]); if (isLoading) { // eslint-disable-next-line react/jsx-no-useless-fragment return <>; } if (loadingSettingsStatus === RequestStatus.DENIED) { return (
); } const handleResetSettingsValues = () => { setIsEditableState(false); showErrorModal(false); setEditedSettings({}); showSaveSettingsPrompt(false); }; const handleSettingBlur = () => { validateAdvancedSettingsData(editedSettings, setErrorFields, setEditedSettings); }; const handleUpdateAdvancedSettingsData = () => { const isValid = validateAdvancedSettingsData(editedSettings, setErrorFields, setEditedSettings); if (isValid) { setIsQueryPending(true); } else { showSaveSettingsPrompt(false); showErrorModal(!errorModal); } }; const handleInternetConnectionFailed = () => { setInternetConnectionError(true); showSaveSettingsPrompt(false); setShowSuccessAlert(false); }; const handleQueryProcessing = () => { setShowSuccessAlert(false); dispatch(updateCourseAppSetting(courseId, parseArrayOrObjectValues(editedSettings))); }; const handleManuallyChangeClick = (setToState) => { showErrorModal(setToState); showSaveSettingsPrompt(true); }; return ( <>
{(proctoringErrors?.length > 0) && (
Warning: }} />
    {Object.keys(advancedSettingsData).map((settingName) => { const settingData = advancedSettingsData[settingName]; if (settingData.deprecated && !showDeprecated) { return null; } return ( ); })}
{isQueryPending && ( )} {intl.formatMessage(messages.buttonCancelText)} ), , ].filter(Boolean)} variant="warning" icon={Warning} title={intl.formatMessage(messages.alertWarning)} description={intl.formatMessage(messages.alertWarningDescriptions)} />
handleManuallyChangeClick(setToState)} handleUndoChanges={handleResetSettingsValues} settingsData={advancedSettingsData} errorList={errorFields.length > 0 ? errorFields : []} /> ); }; AdvancedSettings.propTypes = { courseId: PropTypes.string.isRequired, }; export default AdvancedSettings;