fix: calculator switch click issue and save button animation will be … (#169)
* fix: calculator switch click issue and save button animation will be clickable without any changes * style: remove inline style and fix content display glitch * style: TNL-8566 add padding top for external link * style: TNL-8574 fix badge width and height * fix: resolve console error and remove fix height for modal dialog
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { Form, SwitchControl } from '@edx/paragon';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Form, SwitchControl } from '@edx/paragon';
|
||||
|
||||
import './FormSwitchGroup.scss';
|
||||
|
||||
export default function FormSwitchGroup({
|
||||
id,
|
||||
@@ -23,8 +25,8 @@ export default function FormSwitchGroup({
|
||||
className={className}
|
||||
>
|
||||
<div className="d-flex flex-column">
|
||||
<div className="d-flex flex-row justify-content-between align-items-baseline pb-2">
|
||||
<Form.Label className="h4 text-primary-500 p-0 m-0">
|
||||
<div className="d-flex flex-row justify-content-between align-items-center pb-2 z-index-3">
|
||||
<Form.Label className="h4 text-primary-500 m-0">
|
||||
{label}
|
||||
</Form.Label>
|
||||
<SwitchControl
|
||||
@@ -37,16 +39,12 @@ export default function FormSwitchGroup({
|
||||
/>
|
||||
</div>
|
||||
<Form.Text
|
||||
className="mt-0 pr-3 text-gray-700"
|
||||
style={{
|
||||
fontSize: '1.125rem',
|
||||
}}
|
||||
className="mt-0 text-gray-700 helper-text"
|
||||
id={helpTextId}
|
||||
>
|
||||
{helpText}
|
||||
</Form.Text>
|
||||
</div>
|
||||
|
||||
</Form.Group>
|
||||
);
|
||||
}
|
||||
|
||||
7
src/generic/FormSwitchGroup.scss
Normal file
7
src/generic/FormSwitchGroup.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.helper-text {
|
||||
font-size: 1.125rem !important;
|
||||
}
|
||||
|
||||
.z-index-3 {
|
||||
z-index: 3;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
Form, Hyperlink, ModalDialog, Spinner, TransitionReplace,
|
||||
StatefulButton, Badge, ActionRow,
|
||||
} from '@edx/paragon';
|
||||
import classNames from 'classnames';
|
||||
import { Formik } from 'formik';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import * as Yup from 'yup';
|
||||
@@ -19,6 +20,8 @@ import { PagesAndResourcesContext } from '../PagesAndResourcesProvider';
|
||||
import messages from './messages';
|
||||
import { useIsMobile } from '../../utils';
|
||||
|
||||
import './AppSettingsModal.scss';
|
||||
|
||||
function AppSettingsForm({ formikProps, children }) {
|
||||
return children && (
|
||||
<TransitionReplace>
|
||||
@@ -76,10 +79,7 @@ function AppSettingsModal({
|
||||
}, [updateSettingsRequestStatus]);
|
||||
|
||||
const handleFormSubmit = (values) => {
|
||||
// If the app's enabled/disabled loadingStatus has changed, set that first.
|
||||
if (appInfo.enabled !== values.enabled) {
|
||||
dispatch(updateAppStatus(courseId, appInfo.id, values.enabled, true));
|
||||
}
|
||||
dispatch(updateAppStatus(courseId, appInfo.id, values.enabled));
|
||||
// Call the submit handler for the settings component to save its settings
|
||||
if (onSettingsSave) {
|
||||
onSettingsSave();
|
||||
@@ -99,12 +99,12 @@ function AppSettingsModal({
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
title={title}
|
||||
isOpen
|
||||
closeText={intl.formatMessage(messages.cancel)}
|
||||
dialogClassName="modal-dialog-centered modal-lg"
|
||||
hasCloseButton={isMobile}
|
||||
onClose={onClose}
|
||||
size="md"
|
||||
variant={modalVariant}
|
||||
hasCloseButton={isMobile}
|
||||
isFullscreenOnMobile
|
||||
>
|
||||
{
|
||||
@@ -130,26 +130,31 @@ function AppSettingsModal({
|
||||
{title}
|
||||
</ModalDialog.Title>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<ModalDialog.Body className="overflow-hidden">
|
||||
<FormSwitchGroup
|
||||
id={`enable-${appId}-toggle`}
|
||||
name="enabled"
|
||||
onChange={formikProps.handleChange}
|
||||
onChange={(event) => formikProps.handleChange(event)}
|
||||
onBlur={formikProps.handleBlur}
|
||||
checked={formikProps.values.enabled}
|
||||
label={(
|
||||
<>
|
||||
{enableAppLabel}
|
||||
<div className="d-flex align-items-center">
|
||||
{enableAppLabel}
|
||||
{
|
||||
formikProps.values.enabled && (
|
||||
<Badge className="py-1" variant="success">
|
||||
<Badge className="ml-2" variant="success">
|
||||
{intl.formatMessage(messages.enabled)}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
helpText={(
|
||||
<div>
|
||||
<p>{enableAppHelp}</p>
|
||||
<span className="py-3">{learnMoreLink}</span>
|
||||
</div>
|
||||
)}
|
||||
helpText={(<p>{enableAppHelp}<br /> <span className="pt-3">{learnMoreLink}</span></p>)}
|
||||
/>
|
||||
<AppSettingsForm formikProps={formikProps}>
|
||||
{children}
|
||||
@@ -159,16 +164,23 @@ function AppSettingsModal({
|
||||
{formikProps.values.enabled && children
|
||||
&& <AppConfigFormDivider marginAdj={{ default: 3, sm: null }} />}
|
||||
|
||||
<ModalDialog.Footer style={{ position: 'absolute', width: '100%' }}>
|
||||
<ModalDialog.Footer
|
||||
className={classNames(
|
||||
'p-4',
|
||||
{
|
||||
'modal-footer': isMobile,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<ActionRow>
|
||||
<ModalDialog.CloseButton variant="tertiary">
|
||||
{intl.formatMessage(messages.cancel)}
|
||||
</ModalDialog.CloseButton>
|
||||
<StatefulButton
|
||||
labels={{
|
||||
default: intl.formatMessage(messages.apply),
|
||||
pending: intl.formatMessage(messages.applying),
|
||||
complete: intl.formatMessage(messages.applied),
|
||||
default: intl.formatMessage(messages.save),
|
||||
pending: intl.formatMessage(messages.saving),
|
||||
complete: intl.formatMessage(messages.saved),
|
||||
}}
|
||||
state={submitButtonState}
|
||||
onClick={formikProps.handleSubmit}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.modal-footer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -5,17 +5,17 @@ const messages = defineMessages({
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
},
|
||||
apply: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.apply',
|
||||
defaultMessage: 'Apply',
|
||||
save: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.save',
|
||||
defaultMessage: 'Save',
|
||||
},
|
||||
applying: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.applying',
|
||||
defaultMessage: 'Applying',
|
||||
saving: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.saving',
|
||||
defaultMessage: 'Saving',
|
||||
},
|
||||
applied: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.applied',
|
||||
defaultMessage: 'Applied',
|
||||
saved: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.saved',
|
||||
defaultMessage: 'Saved',
|
||||
},
|
||||
retry: {
|
||||
id: 'course-authoring.pages-resources.app-settings-modal.button.retry',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Card, Form } from '@edx/paragon';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Formik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
@@ -11,7 +10,6 @@ import AnonymousPostingFields from '../shared/AnonymousPostingFields';
|
||||
import DiscussionTopics from '../shared/discussion-topics/DiscussionTopics';
|
||||
import BlackoutDatesField, { blackoutDatesRegex } from '../shared/BlackoutDatesField';
|
||||
import LegacyConfigFormProvider from './LegacyConfigFormProvider';
|
||||
import { updateValidationStatus } from '../../../data/slice';
|
||||
|
||||
import messages from '../shared/messages';
|
||||
import AppConfigFormDivider from '../shared/AppConfigFormDivider';
|
||||
@@ -39,13 +37,6 @@ Yup.addMethod(Yup.object, 'uniqueProperty', function (propertyName, message) {
|
||||
function LegacyConfigForm({
|
||||
appConfig, onSubmit, formRef, intl, title,
|
||||
}) {
|
||||
const [isFormInvalid, setIsFormInvalid] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updateValidationStatus({ hasError: isFormInvalid }));
|
||||
}, [isFormInvalid]);
|
||||
|
||||
const [validDiscussionTopics, setValidDiscussionTopics] = useState(appConfig.discussionTopics);
|
||||
const legacyFormValidationSchema = Yup.object().shape({
|
||||
blackoutDates: Yup.string().matches(
|
||||
@@ -87,9 +78,9 @@ function LegacyConfigForm({
|
||||
validDiscussionTopics,
|
||||
setValidDiscussionTopics,
|
||||
discussionTopicErrors,
|
||||
isFormInvalid: discussionTopicErrors.some((error) => error === true)
|
||||
|| Boolean(touched.blackoutDates && errors.blackoutDates),
|
||||
};
|
||||
setIsFormInvalid(discussionTopicErrors.some((error) => error === true)
|
||||
|| Boolean(touched.blackoutDates && errors.blackoutDates));
|
||||
|
||||
return (
|
||||
<LegacyConfigFormProvider value={contextValue}>
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import React, { createContext } from 'react';
|
||||
import React, { createContext, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { updateValidationStatus } from '../../../data/slice';
|
||||
|
||||
export const LegacyConfigFormContext = createContext({});
|
||||
|
||||
export default function LegacyConfigFormProvider({ children, value }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(updateValidationStatus({ hasError: value.isFormInvalid }));
|
||||
}, [value.isFormInvalid]);
|
||||
|
||||
return (
|
||||
<LegacyConfigFormContext.Provider value={value}>
|
||||
{children}
|
||||
@@ -22,5 +30,6 @@ LegacyConfigFormProvider.propTypes = {
|
||||
})),
|
||||
setValidDiscussionTopics: PropTypes.func,
|
||||
})),
|
||||
isFormInvalid: PropTypes.bool,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
@@ -68,19 +68,19 @@ function PageCard({
|
||||
)}
|
||||
>
|
||||
<Card.Body className="d-flex flex-column justify-content-between">
|
||||
<Card.Title className="d-flex mb-0 align-items-center justify-content-between">
|
||||
<h4 className="m-0 p-0">{page.name}</h4>
|
||||
<SettingsButton />
|
||||
</Card.Title>
|
||||
|
||||
{
|
||||
page.enabled && (
|
||||
<Badge className="py-1" variant="success">
|
||||
{intl.formatMessage(messages.enabled)}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
|
||||
<div>
|
||||
<Card.Title className="d-flex mb-1 align-items-center justify-content-between">
|
||||
<h4 className="m-0 p-0">{page.name}</h4>
|
||||
<SettingsButton />
|
||||
</Card.Title>
|
||||
{
|
||||
page.enabled && (
|
||||
<Badge variant="success">
|
||||
{intl.formatMessage(messages.enabled)}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<Card.Text className="m-0">
|
||||
{page.description}
|
||||
</Card.Text>
|
||||
|
||||
@@ -14,8 +14,8 @@ function PageGrid({ pages }) {
|
||||
}}
|
||||
>
|
||||
{pages.map((page) => (
|
||||
<div className="justify-content-center w-100 d-flex">
|
||||
<PageCard key={page.id} page={page} />
|
||||
<div key={page.id} className="justify-content-center w-100 d-flex">
|
||||
<PageCard page={page} />
|
||||
</div>
|
||||
))}
|
||||
</CardGrid>
|
||||
|
||||
Reference in New Issue
Block a user