Skip to content

Commit 2b3cf2a

Browse files
committed
refactor: convert AddComponent to typescript
1 parent d652eda commit 2b3cf2a

4 files changed

Lines changed: 57 additions & 50 deletions

File tree

src/course-unit/add-component/AddComponent.test.jsx renamed to src/course-unit/add-component/AddComponent.test.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { fetchCourseSectionVerticalData } from '../data/thunk';
1414
import { getCourseSectionVerticalApiUrl } from '../data/api';
1515
import { courseSectionVerticalMock } from '../__mocks__';
1616
import { COMPONENT_TYPES } from '../../generic/block-type-utils/constants';
17-
import AddComponent from './AddComponent';
17+
import AddComponent, { AddComponentProps } from './AddComponent';
1818
import messages from './messages';
1919
import { IframeProvider } from '../../generic/hooks/context/iFrameContext';
2020
import { messageTypes } from '../constants';
@@ -56,13 +56,11 @@ jest.mock('../../generic/hooks/context/hooks', () => ({
5656
}),
5757
}));
5858

59-
const renderComponent = (props) => render(
59+
const renderComponent = (props?: AddComponentProps) => render(
6060
<IframeProvider>
6161
<AddComponent
62-
blockId={blockId}
6362
isUnitVerticalType
6463
parentLocator={blockId}
65-
addComponentTemplateData={{}}
6664
handleCreateNewCourseXBlock={handleCreateNewCourseXBlockMock}
6765
{...props}
6866
/>
@@ -94,7 +92,7 @@ describe('<AddComponent />', () => {
9492
),
9593
});
9694
expect(btn).toBeInTheDocument();
97-
if (component.beta) {
95+
if (componentTemplates[component].beta) {
9896
expect(within(btn).queryByText('Beta')).toBeInTheDocument();
9997
}
10098
});

src/course-unit/add-component/AddComponent.jsx renamed to src/course-unit/add-component/AddComponent.tsx

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useCallback, useState } from 'react';
2-
import PropTypes from 'prop-types';
32
import { useDispatch, useSelector } from 'react-redux';
43
import { getConfig } from '@edx/frontend-platform';
54
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
@@ -21,6 +20,41 @@ import { useEventListener } from '../../generic/hooks';
2120
import VideoSelectorPage from '../../editors/VideoSelectorPage';
2221
import EditorPage from '../../editors/EditorPage';
2322
import { fetchCourseSectionVerticalData } from '../data/thunk';
23+
import { SelectedComponent } from '../../library-authoring';
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

2559
const AddComponent = ({
2660
parentLocator,
@@ -29,24 +63,24 @@ const AddComponent = ({
2963
isProblemBankType,
3064
addComponentTemplateData,
3165
handleCreateNewCourseXBlock,
32-
}) => {
66+
}: AddComponentProps) => {
3367
const intl = useIntl();
3468
const dispatch = useDispatch();
3569

3670
const [isOpenAdvanced, openAdvanced, closeAdvanced] = useToggle(false);
3771
const [isOpenHtml, openHtml, closeHtml] = useToggle(false);
3872
const [isOpenOpenAssessment, openOpenAssessment, closeOpenAssessment] = useToggle(false);
3973
const { componentTemplates = {} } = useSelector(getCourseSectionVertical);
40-
const blockId = addComponentTemplateData.parentLocator || parentLocator;
74+
const blockId = addComponentTemplateData?.parentLocator || parentLocator;
4175
const [isAddLibraryContentModalOpen, showAddLibraryContentModal, closeAddLibraryContentModal] = useToggle();
4276
const [isVideoSelectorModalOpen, showVideoSelectorModal, closeVideoSelectorModal] = useToggle();
4377
const [isXBlockEditorModalOpen, showXBlockEditorModal, closeXBlockEditorModal] = useToggle();
4478

45-
const [blockType, setBlockType] = useState(null);
46-
const [courseId, setCourseId] = useState(null);
47-
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);
4882
const [isSelectLibraryContentModalOpen, showSelectLibraryContentModal, closeSelectLibraryContentModal] = useToggle();
49-
const [selectedComponents, setSelectedComponents] = useState([]);
83+
const [selectedComponents, setSelectedComponents] = useState<SelectedComponent[]>([]);
5084
const [usageId, setUsageId] = useState(null);
5185
const { sendMessageToIframe } = useIframe();
5286
const { useVideoGalleryFlow } = useWaffleFlags(courseId ?? undefined);
@@ -85,7 +119,7 @@ const AddComponent = ({
85119
dispatch(fetchCourseSectionVerticalData(blockId, sequenceId));
86120
}, [closeXBlockEditorModal, closeVideoSelectorModal, sendMessageToIframe, blockId, sequenceId]);
87121

88-
const handleLibraryV2Selection = useCallback((selection) => {
122+
const handleLibraryV2Selection = useCallback((selection: SelectedComponent) => {
89123
handleCreateNewCourseXBlock({
90124
type: COMPONENT_TYPES.libraryV2,
91125
category: selection.blockType,
@@ -95,7 +129,7 @@ const AddComponent = ({
95129
closeAddLibraryContentModal();
96130
}, [usageId]);
97131

98-
const handleCreateNewXBlock = (type, moduleName) => {
132+
const handleCreateNewXBlock = (type: string, moduleName?: string) => {
99133
switch (type) {
100134
case COMPONENT_TYPES.discussion:
101135
case COMPONENT_TYPES.dragAndDrop:
@@ -164,9 +198,9 @@ const AddComponent = ({
164198
<>
165199
<h5 className="h3 mb-4 text-center">{intl.formatMessage(messages.title)}</h5>
166200
<ul className="new-component-type list-unstyled m-0 d-flex flex-wrap justify-content-center">
167-
{componentTemplates.map((component) => {
201+
{componentTemplates.map((component: ComponentTemplateData) => {
168202
const { type, displayName, beta } = component;
169-
let modalParams;
203+
let modalParams: { open: () => void, close: () => void, isOpen: boolean };
170204

171205
if (!component.templates.length) {
172206
return null;
@@ -269,7 +303,7 @@ const AddComponent = ({
269303
/>
270304
</div>
271305
</StandardModal>
272-
{isXBlockEditorModalOpen && (
306+
{isXBlockEditorModalOpen && courseId && blockType && newBlockId && (
273307
<div className="editor-page">
274308
<EditorPage
275309
courseId={courseId}
@@ -289,32 +323,4 @@ const AddComponent = ({
289323
return null;
290324
};
291325

292-
AddComponent.propTypes = {
293-
isSplitTestType: PropTypes.bool.isRequired,
294-
isUnitVerticalType: PropTypes.bool.isRequired,
295-
parentLocator: PropTypes.string.isRequired,
296-
handleCreateNewCourseXBlock: PropTypes.func.isRequired,
297-
addComponentTemplateData: {
298-
blockId: PropTypes.string.isRequired,
299-
model: PropTypes.shape({
300-
displayName: PropTypes.string.isRequired,
301-
category: PropTypes.string,
302-
type: PropTypes.string.isRequired,
303-
templates: PropTypes.arrayOf(
304-
PropTypes.shape({
305-
boilerplateName: PropTypes.string,
306-
category: PropTypes.string,
307-
displayName: PropTypes.string.isRequired,
308-
supportLevel: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
309-
}),
310-
),
311-
supportLegend: PropTypes.shape({
312-
allowUnsupportedXblocks: PropTypes.bool,
313-
documentationLabel: PropTypes.string,
314-
showLegend: PropTypes.bool,
315-
}),
316-
}),
317-
},
318-
};
319-
320326
export default AddComponent;

src/course-unit/hooks.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ export const useCourseUnit = ({ courseId, blockId }) => {
7272
const isUnitVerticalType = unitCategory === COURSE_BLOCK_NAMES.vertical.id;
7373
const isUnitLibraryType = unitCategory === COURSE_BLOCK_NAMES.libraryContent.id;
7474
const isSplitTestType = unitCategory === COURSE_BLOCK_NAMES.splitTest.id;
75-
const isProblemBankType = [COURSE_BLOCK_NAMES.legacyLibraryContent.id, COURSE_BLOCK_NAMES.itembank.id].includes(unitCategory);
75+
const isProblemBankType = [
76+
COURSE_BLOCK_NAMES.legacyLibraryContent.id,
77+
COURSE_BLOCK_NAMES.itembank.id,
78+
].includes(unitCategory);
7679

7780
const headerNavigationsActions = {
7881
handleViewLive: () => {

src/library-authoring/component-picker/ComponentPicker.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ type ComponentPickerProps = {
5656
} & (
5757
{
5858
componentPickerMode?: 'single',
59-
onComponentSelected?: ComponentSelectedEvent,
60-
onChangeComponentSelection?: never,
59+
onComponentSelected: ComponentSelectedEvent,
60+
onChangeComponentSelection?: ComponentSelectionChangedEvent,
6161
} | {
62-
componentPickerMode: 'multiple'
63-
onComponentSelected?: never,
62+
componentPickerMode?: 'multiple'
63+
onComponentSelected?: ComponentSelectedEvent,
6464
onChangeComponentSelection?: ComponentSelectionChangedEvent,
6565
}
6666
);

0 commit comments

Comments
 (0)