@@ -46,24 +46,26 @@ import {
4646} from "../../constants/ActivityLabels" ;
4747import * as Routes from "../../constants/Routes" ;
4848import { COURSE_PAGE } from "../../constants/Routes" ;
49+ import { useCourseUnits } from "../../contexts/CourseUnitsContext" ;
50+ import { useSocket } from "../../contexts/SocketContext" ;
4951import useActivity from "../../hooks/useActivity" ;
5052import useQueryParams from "../../hooks/useQueryParams" ;
5153import { useUser } from "../../hooks/useUser" ;
5254import {
5355 Activity ,
5456 CourseModule ,
5557 CourseUnit ,
58+ HeaderColumnIncludesTypes ,
5659 isActivityPage ,
5760 isLessonPage ,
5861 isMatchingActivity ,
5962 isMultipleChoiceActivity ,
6063 isMultiSelectActivity ,
6164 isTableActivity ,
62- HeaderColumnIncludesTypes ,
65+ isTextInputActivity ,
6366 Media ,
64- QuestionType ,
6567 ModuleStatus ,
66- isTextInputActivity ,
68+ QuestionType ,
6769} from "../../types/CourseTypes" ;
6870import { Bookmark } from "../../types/UserTypes" ;
6971import { padNumber } from "../../utils/StringUtils" ;
@@ -78,26 +80,24 @@ import MultipleChoiceMainEditor from "../course_authoring/multiple-choice/Multip
7880import MultipleChoiceEditorSidebar from "../course_authoring/multiple-choice/MultipleChoiceSidebar" ;
7981import TableMainEditor from "../course_authoring/table/TableEditor" ;
8082import TableSidebar from "../course_authoring/table/TableSidebar" ;
83+ import TextInputEditor from "../course_authoring/text-input/TextInputEditor" ;
84+ import TextInputEditorSidebar from "../course_authoring/text-input/TextInputSidebar" ;
8185import MatchingViewer from "../course_viewing/matching/MatchingViewer" ;
86+ import EditPublishedModuleModal from "../course_viewing/modals/EditPublishedModuleModal" ;
87+ import PublishModuleModal from "../course_viewing/modals/PublishModuleModal" ;
8288import WrongAnswerModal from "../course_viewing/modals/WrongAnswerModal" ;
8389import MultipleChoiceViewer , {
8490 ActivityViewerHandle ,
8591} from "../course_viewing/multiple-choice/MultipleChoiceViewer" ;
8692import TableViewer from "../course_viewing/table/TableViewer" ;
93+ import TextInputViewer from "../course_viewing/text-input/TextInputViewer" ;
8794import FeedbackThumbnail from "../courses/moduleViewing/learner-giving-feedback/FeedbackThumbnail" ;
8895import SurveySlides from "../courses/moduleViewing/learner-giving-feedback/SurveySlides" ;
8996import ModuleSidebarThumbnail from "../courses/moduleViewing/Thumbnail" ;
9097import NeedHelpModal from "../help/NeedHelpModal" ;
9198import DeletePageModal from "./DeletePageModal" ;
9299import ModuleLockedModal from "./ModuleLockedModal" ;
93100import "./ViewModulePage.css" ;
94- import { useCourseUnits } from "../../contexts/CourseUnitsContext" ;
95- import EditPublishedModuleModal from "../course_viewing/modals/EditPublishedModuleModal" ;
96- import { useSocket } from "../../contexts/SocketContext" ;
97- import PublishModuleModal from "../course_viewing/modals/PublishModuleModal" ;
98- import TextInputEditorSidebar from "../course_authoring/text-input/TextInputSidebar" ;
99- import TextInputEditor from "../course_authoring/text-input/TextInputEditor" ;
100- import TextInputViewer from "../course_viewing/text-input/TextInputViewer" ;
101101
102102pdfjs . GlobalWorkerOptions . workerSrc = new URL (
103103 "pdfjs-dist/build/pdf.worker.min.mjs" ,
@@ -156,6 +156,8 @@ const ViewModulePage = () => {
156156 mouseX : number ;
157157 mouseY : number ;
158158 pageIndex : number ;
159+ addToEnd : boolean ;
160+ open : boolean ;
159161 } | null > ( null ) ;
160162 const [ activityMenuAnchor , setActivityMenuAnchor ] =
161163 useState < null | HTMLElement > ( null ) ;
@@ -268,14 +270,16 @@ const ViewModulePage = () => {
268270 } , [ activity ] ) ;
269271
270272 const handleContextMenu = useCallback (
271- ( event : React . MouseEvent < HTMLDivElement > , pageIndex : number ) => {
273+ ( event : React . MouseEvent , pageIndex : number , addToEnd = false ) => {
272274 event . preventDefault ( ) ;
273275 setContextMenu ( ( prev ) =>
274- prev === null
276+ prev === null || ! prev . open
275277 ? {
276278 mouseX : event . clientX + 2 ,
277279 mouseY : event . clientY - 6 ,
278280 pageIndex,
281+ addToEnd,
282+ open : true ,
279283 }
280284 : null ,
281285 ) ;
@@ -284,7 +288,7 @@ const ViewModulePage = () => {
284288 ) ;
285289
286290 const handleCloseContextMenu = useCallback ( ( ) => {
287- setContextMenu ( null ) ;
291+ setContextMenu ( ( prev ) => ( prev ? { ... prev , open : false } : null ) ) ;
288292 } , [ ] ) ;
289293
290294 const handleUploadPdfAbove = ( ) => {
@@ -367,7 +371,6 @@ const ViewModulePage = () => {
367371 if ( contextMenu === null ) return ;
368372 setSelectedPageIndexForActivity ( contextMenu . pageIndex ) ;
369373 setActivityMenuAnchor ( event . currentTarget ) ;
370- handleCloseContextMenu ( ) ;
371374 } ;
372375
373376 const handleActivityTypeSelect = async ( questionType : QuestionType ) => {
@@ -385,6 +388,7 @@ const ViewModulePage = () => {
385388 /* eslint-disable-next-line no-console */
386389 console . error ( "Failed to create activity:" , error ) ;
387390 }
391+ handleCloseContextMenu ( ) ;
388392 setActivityMenuAnchor ( null ) ;
389393 setSelectedPageIndexForActivity ( null ) ;
390394 } ;
@@ -1437,11 +1441,18 @@ const ViewModulePage = () => {
14371441 </ Typography >
14381442 < IconButton
14391443 disabled = {
1440- role === "Learner" && module && isModuleCompleted ( module . id )
1444+ role !== "Administrator" &&
1445+ ( role === "Learner" && module && isModuleCompleted ( module . id )
14411446 ? currentPage >= numPages
1442- : currentPage >= numPages - 1
1447+ : currentPage >= numPages - 1 )
14431448 }
1444- onClick = { ( ) => setCurrentPage ( currentPage + 1 ) }
1449+ onClick = { ( event ) => {
1450+ if ( role === "Administrator" && currentPage + 1 >= numPages ) {
1451+ handleContextMenu ( event , currentPage , true ) ;
1452+ } else {
1453+ setCurrentPage ( currentPage + 1 ) ;
1454+ }
1455+ } }
14451456 sx = { {
14461457 border : "1px solid black" ,
14471458 height : "48px" ,
@@ -1679,23 +1690,30 @@ const ViewModulePage = () => {
16791690 />
16801691 ) }
16811692 < Menu
1682- open = { contextMenu !== null }
1693+ open = { contextMenu !== null && contextMenu . open }
16831694 onClose = { handleCloseContextMenu }
16841695 anchorReference = "anchorPosition"
16851696 anchorPosition = {
1686- contextMenu !== null
1697+ contextMenu !== null && contextMenu . open
16871698 ? { top : contextMenu . mouseY , left : contextMenu . mouseX }
16881699 : undefined
16891700 }
16901701 >
1691- < MenuItem
1692- onClick = { handleUploadPdfAbove }
1693- disabled = { isUploadingPdf || isDeletingFromContext }
1694- >
1695- < Stack direction = "row" alignItems = "center" gap = "12px" paddingY = "8px" >
1696- < ArrowCircleUp /> Insert pages above
1697- </ Stack >
1698- </ MenuItem >
1702+ { ! contextMenu ?. addToEnd && (
1703+ < MenuItem
1704+ onClick = { handleUploadPdfAbove }
1705+ disabled = { isUploadingPdf || isDeletingFromContext }
1706+ >
1707+ < Stack
1708+ direction = "row"
1709+ alignItems = "center"
1710+ gap = "12px"
1711+ paddingY = "8px"
1712+ >
1713+ < ArrowCircleUp /> Insert pages above
1714+ </ Stack >
1715+ </ MenuItem >
1716+ ) }
16991717 < MenuItem
17001718 onClick = { handleUploadPdfBelow }
17011719 disabled = { isUploadingPdf || isDeletingFromContext }
@@ -1712,36 +1730,43 @@ const ViewModulePage = () => {
17121730 < Add /> Create activity
17131731 </ Stack >
17141732 </ MenuItem >
1715- < MenuItem
1716- onClick = { handleDeletePageFromContext }
1717- disabled = { isUploadingPdf || isDeletingFromContext }
1718- >
1719- < Stack
1720- direction = "row"
1721- alignItems = "center"
1722- gap = "12px"
1723- color = { theme . palette . Error . Dark . Default }
1724- paddingY = "8px"
1733+ { ! contextMenu ?. addToEnd && (
1734+ < MenuItem
1735+ onClick = { handleDeletePageFromContext }
1736+ disabled = { isUploadingPdf || isDeletingFromContext }
17251737 >
1726- < DeleteOutline /> Delete page
1727- </ Stack >
1728- </ MenuItem >
1738+ < Stack
1739+ direction = "row"
1740+ alignItems = "center"
1741+ gap = "12px"
1742+ color = { theme . palette . Error . Dark . Default }
1743+ paddingY = "8px"
1744+ >
1745+ < DeleteOutline /> Delete page
1746+ </ Stack >
1747+ </ MenuItem >
1748+ ) }
17291749 </ Menu >
17301750 < Menu
17311751 id = "activity-type-menu"
17321752 anchorEl = { activityMenuAnchor }
17331753 open = { Boolean ( activityMenuAnchor ) }
17341754 onClose = { ( ) => {
1735- setActivityMenuAnchor ( null ) ;
17361755 setSelectedPageIndexForActivity ( null ) ;
1756+ setActivityMenuAnchor ( null ) ;
17371757 } }
17381758 MenuListProps = { {
17391759 "aria-labelledby" : "activity-type-button" ,
17401760 } }
17411761 >
17421762 { Object . values ( QuestionType ) . map ( ( type ) => (
17431763 < MenuItem key = { type } onClick = { ( ) => handleActivityTypeSelect ( type ) } >
1744- < Stack direction = "row" alignItems = "center" gap = "8px" >
1764+ < Stack
1765+ direction = "row"
1766+ alignItems = "center"
1767+ gap = "8px"
1768+ color = { theme . palette . Administrator . Dark . Default }
1769+ >
17451770 { questionTypeIcons [ type ] } { questionTypeLabels [ type ] }
17461771 </ Stack >
17471772 </ MenuItem >
0 commit comments