11import { useCallback , useState } from 'react' ;
2- import PropTypes from 'prop-types' ;
32import { useDispatch , useSelector } from 'react-redux' ;
43import { getConfig } from '@edx/frontend-platform' ;
54import { useIntl , FormattedMessage } from '@edx/frontend-platform/i18n' ;
65import {
76 ActionRow , Button , StandardModal , useToggle ,
87} from '@openedx/paragon' ;
98
10- import { getCourseSectionVertical , getCourseUnitData } from '../data/selectors' ;
11- import { useWaffleFlags } from '../../data/apiHooks' ;
12- import { COMPONENT_TYPES } from '../../generic/block-type-utils/constants' ;
13- import ComponentModalView from './add-component-modals/ComponentModalView' ;
14- import AddComponentButton from './add-component-btn' ;
15- import messages from './messages' ;
16- import { ComponentPicker } from '../../library-authoring/component-picker' ;
17- import { ContentType } from '../../library-authoring/routes' ;
18- import { messageTypes } from '../constants' ;
19- import { useIframe } from '../../generic/hooks/context/hooks' ;
20- import { useEventListener } from '../../generic/hooks' ;
21- import VideoSelectorPage from '../../editors/VideoSelectorPage' ;
22- import EditorPage from '../../editors/EditorPage' ;
9+ import { useWaffleFlags } from '@src/data/apiHooks' ;
10+ import { COMPONENT_TYPES } from '@src/generic/block-type-utils/constants' ;
11+ import { ComponentPicker } from '@src/library-authoring/component-picker' ;
12+ import { ContentType } from '@src/library-authoring/routes' ;
13+ import { useIframe } from '@src/generic/hooks/context/hooks' ;
14+ import { useEventListener } from '@src/generic/hooks' ;
15+ import VideoSelectorPage from '@src/editors/VideoSelectorPage' ;
16+ import EditorPage from '@src/editors/EditorPage' ;
17+ import { SelectedComponent } from '@src/library-authoring' ;
2318import { fetchCourseSectionVerticalData } from '../data/thunk' ;
19+ import { messageTypes } from '../constants' ;
20+ import messages from './messages' ;
21+ import AddComponentButton from './add-component-btn' ;
22+ import ComponentModalView from './add-component-modals/ComponentModalView' ;
23+ import { getCourseSectionVertical , getCourseUnitData } from '../data/selectors' ;
24+
25+ type ComponentTemplateData = {
26+ displayName : string ,
27+ category ?: string ,
28+ type : string ,
29+ beta ?: boolean ,
30+ templates : Array < {
31+ boilerplateName ?: string ,
32+ category ?: string ,
33+ displayName : string ,
34+ supportLevel ?: string | boolean ,
35+ } > ,
36+ supportLegend : {
37+ allowUnsupportedXblocks ?: boolean ,
38+ documentationLabel ?: string ,
39+ showLegend ?: boolean ,
40+ } ,
41+ } ;
42+
43+ export interface AddComponentProps {
44+ isSplitTestType ?: boolean ,
45+ isUnitVerticalType ?: boolean ,
46+ parentLocator : string ,
47+ handleCreateNewCourseXBlock : (
48+ args : object ,
49+ callback ?: ( args : { courseKey : string , locator : string } ) => void
50+ ) => void ,
51+ isProblemBankType ?: boolean ,
52+ addComponentTemplateData ?: {
53+ blockId : string ,
54+ parentLocator ?: string ,
55+ model : ComponentTemplateData ,
56+ } ,
57+ }
2458
2559const AddComponent = ( {
2660 parentLocator,
2761 isSplitTestType,
2862 isUnitVerticalType,
63+ isProblemBankType,
2964 addComponentTemplateData,
3065 handleCreateNewCourseXBlock,
31- } ) => {
66+ } : AddComponentProps ) => {
3267 const intl = useIntl ( ) ;
3368 const dispatch = useDispatch ( ) ;
3469
3570 const [ isOpenAdvanced , openAdvanced , closeAdvanced ] = useToggle ( false ) ;
3671 const [ isOpenHtml , openHtml , closeHtml ] = useToggle ( false ) ;
3772 const [ isOpenOpenAssessment , openOpenAssessment , closeOpenAssessment ] = useToggle ( false ) ;
3873 const { componentTemplates = { } } = useSelector ( getCourseSectionVertical ) ;
39- const blockId = addComponentTemplateData . parentLocator || parentLocator ;
74+ const blockId = addComponentTemplateData ? .parentLocator || parentLocator ;
4075 const [ isAddLibraryContentModalOpen , showAddLibraryContentModal , closeAddLibraryContentModal ] = useToggle ( ) ;
4176 const [ isVideoSelectorModalOpen , showVideoSelectorModal , closeVideoSelectorModal ] = useToggle ( ) ;
4277 const [ isXBlockEditorModalOpen , showXBlockEditorModal , closeXBlockEditorModal ] = useToggle ( ) ;
4378
44- const [ blockType , setBlockType ] = useState ( null ) ;
45- const [ courseId , setCourseId ] = useState ( null ) ;
46- const [ newBlockId , setNewBlockId ] = useState ( null ) ;
79+ const [ blockType , setBlockType ] = useState < string | null > ( null ) ;
80+ const [ courseId , setCourseId ] = useState < string | null > ( null ) ;
81+ const [ newBlockId , setNewBlockId ] = useState < string | null > ( null ) ;
4782 const [ isSelectLibraryContentModalOpen , showSelectLibraryContentModal , closeSelectLibraryContentModal ] = useToggle ( ) ;
48- const [ selectedComponents , setSelectedComponents ] = useState ( [ ] ) ;
83+ const [ selectedComponents , setSelectedComponents ] = useState < SelectedComponent [ ] > ( [ ] ) ;
4984 const [ usageId , setUsageId ] = useState ( null ) ;
5085 const { sendMessageToIframe } = useIframe ( ) ;
5186 const { useVideoGalleryFlow } = useWaffleFlags ( courseId ?? undefined ) ;
@@ -84,7 +119,7 @@ const AddComponent = ({
84119 dispatch ( fetchCourseSectionVerticalData ( blockId , sequenceId ) ) ;
85120 } , [ closeXBlockEditorModal , closeVideoSelectorModal , sendMessageToIframe , blockId , sequenceId ] ) ;
86121
87- const handleLibraryV2Selection = useCallback ( ( selection ) => {
122+ const handleLibraryV2Selection = useCallback ( ( selection : SelectedComponent ) => {
88123 handleCreateNewCourseXBlock ( {
89124 type : COMPONENT_TYPES . libraryV2 ,
90125 category : selection . blockType ,
@@ -94,7 +129,7 @@ const AddComponent = ({
94129 closeAddLibraryContentModal ( ) ;
95130 } , [ usageId ] ) ;
96131
97- const handleCreateNewXBlock = ( type , moduleName ) => {
132+ const handleCreateNewXBlock = ( type : string , moduleName ?: string ) => {
98133 switch ( type ) {
99134 case COMPONENT_TYPES . discussion :
100135 case COMPONENT_TYPES . dragAndDrop :
@@ -156,16 +191,16 @@ const AddComponent = ({
156191 }
157192 } ;
158193
159- if ( isUnitVerticalType || isSplitTestType ) {
194+ if ( isUnitVerticalType || isSplitTestType || isProblemBankType ) {
160195 return (
161196 < div className = "py-4" >
162197 { Object . keys ( componentTemplates ) . length && isUnitVerticalType ? (
163198 < >
164199 < h5 className = "h3 mb-4 text-center" > { intl . formatMessage ( messages . title ) } </ h5 >
165200 < ul className = "new-component-type list-unstyled m-0 d-flex flex-wrap justify-content-center" >
166- { componentTemplates . map ( ( component ) => {
201+ { componentTemplates . map ( ( component : ComponentTemplateData ) => {
167202 const { type, displayName, beta } = component ;
168- let modalParams ;
203+ let modalParams : { open : ( ) => void , close : ( ) => void , isOpen : boolean } ;
169204
170205 if ( ! component . templates . length ) {
171206 return null ;
@@ -268,7 +303,7 @@ const AddComponent = ({
268303 />
269304 </ div >
270305 </ StandardModal >
271- { isXBlockEditorModalOpen && (
306+ { isXBlockEditorModalOpen && courseId && blockType && newBlockId && (
272307 < div className = "editor-page" >
273308 < EditorPage
274309 courseId = { courseId }
@@ -288,32 +323,4 @@ const AddComponent = ({
288323 return null ;
289324} ;
290325
291- AddComponent . propTypes = {
292- isSplitTestType : PropTypes . bool . isRequired ,
293- isUnitVerticalType : PropTypes . bool . isRequired ,
294- parentLocator : PropTypes . string . isRequired ,
295- handleCreateNewCourseXBlock : PropTypes . func . isRequired ,
296- addComponentTemplateData : {
297- blockId : PropTypes . string . isRequired ,
298- model : PropTypes . shape ( {
299- displayName : PropTypes . string . isRequired ,
300- category : PropTypes . string ,
301- type : PropTypes . string . isRequired ,
302- templates : PropTypes . arrayOf (
303- PropTypes . shape ( {
304- boilerplateName : PropTypes . string ,
305- category : PropTypes . string ,
306- displayName : PropTypes . string . isRequired ,
307- supportLevel : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . bool ] ) ,
308- } ) ,
309- ) ,
310- supportLegend : PropTypes . shape ( {
311- allowUnsupportedXblocks : PropTypes . bool ,
312- documentationLabel : PropTypes . string ,
313- showLegend : PropTypes . bool ,
314- } ) ,
315- } ) ,
316- } ,
317- } ;
318-
319326export default AddComponent ;
0 commit comments