Skip to content

Commit db4e71a

Browse files
committed
feat: Enable Move menus in subsections
1 parent a39678b commit db4e71a

9 files changed

Lines changed: 134 additions & 67 deletions

File tree

src/CourseAuthoringContext.tsx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getConfig } from '@edx/frontend-platform';
22
import {
3-
createContext, useContext, useMemo, useState,
3+
createContext, useContext, useEffect, useMemo, useState,
44
} from 'react';
55
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
66
import { useCreateCourseBlock, useDuplicateItem } from '@src/course-outline/data/apiHooks';
@@ -13,7 +13,7 @@ import { CourseDetailsData } from './data/api';
1313
import { useCourseDetails, useWaffleFlags } from './data/apiHooks';
1414
import { RequestStatusType } from './data/constants';
1515
import { arrayMove } from '@dnd-kit/sortable';
16-
import { setSectionOrderListQuery } from './course-outline/data/thunk';
16+
import { fetchCourseOutlineIndexQuery, setSectionOrderListQuery, setSubsectionOrderListQuery } from './course-outline/data/thunk';
1717

1818
type ModalState = {
1919
value?: XBlock | UnitXBlock;
@@ -50,7 +50,9 @@ export type CourseAuthoringContextData = {
5050
handleDuplicateSubsectionSubmit: () => void;
5151
handleDuplicateUnitSubmit: () => void;
5252
handleSectionDragAndDrop: (sectionListIds: string[]) => void;
53+
handleSubsectionDragAndDrop: (sectionId: string, prevSectionId: string, subsectionListIds: string[]) => void;
5354
updateSectionOrderByIndex: (currentIndex: number, newIndex: number) => void;
55+
updateSubsectionOrderByIndex: (section: XBlock, moveDetails: any) => void;
5456
};
5557

5658
/**
@@ -97,6 +99,14 @@ export const CourseAuthoringProvider = ({
9799
setSections(() => [...sectionsList]);
98100
};
99101

102+
useEffect(() => {
103+
dispatch(fetchCourseOutlineIndexQuery(courseId));
104+
}, [courseId]);
105+
106+
useEffect(() => {
107+
setSections(sectionsList);
108+
}, [sectionsList]);
109+
100110
/**
101111
* This will hold the state of current item that is being operated on,
102112
* For example:
@@ -179,6 +189,19 @@ export const CourseAuthoringProvider = ({
179189
));
180190
};
181191

192+
const handleSubsectionDragAndDrop = (
193+
sectionId: string,
194+
prevSectionId: string,
195+
subsectionListIds: string[],
196+
) => {
197+
dispatch(setSubsectionOrderListQuery(
198+
sectionId,
199+
prevSectionId,
200+
subsectionListIds,
201+
restoreSectionList,
202+
));
203+
};
204+
182205
/**
183206
* Move section to new index
184207
*/
@@ -193,6 +216,25 @@ export const CourseAuthoringProvider = ({
193216
});
194217
};
195218

219+
/**
220+
* Uses details from move information and moves subsection
221+
*/
222+
const updateSubsectionOrderByIndex = (section: XBlock, moveDetails) => {
223+
const { fn, args, sectionId } = moveDetails;
224+
if (!args) {
225+
return;
226+
}
227+
const [sectionsCopy, newSubsections] = fn(...args);
228+
if (newSubsections && sectionId) {
229+
setSections(sectionsCopy);
230+
handleSubsectionDragAndDrop(
231+
sectionId,
232+
section.id,
233+
newSubsections.map(subsection => subsection.id),
234+
);
235+
}
236+
};
237+
196238
const context = useMemo<CourseAuthoringContextData>(() => ({
197239
courseId,
198240
courseUsageKey,
@@ -221,7 +263,9 @@ export const CourseAuthoringProvider = ({
221263
handleDuplicateSubsectionSubmit,
222264
handleDuplicateUnitSubmit,
223265
handleSectionDragAndDrop,
266+
handleSubsectionDragAndDrop,
224267
updateSectionOrderByIndex,
268+
updateSubsectionOrderByIndex,
225269
}), [
226270
courseId,
227271
courseUsageKey,
@@ -249,7 +293,9 @@ export const CourseAuthoringProvider = ({
249293
handleDuplicateSectionSubmit,
250294
handleDuplicateSubsectionSubmit,
251295
handleSectionDragAndDrop,
296+
handleSubsectionDragAndDrop,
252297
updateSectionOrderByIndex,
298+
updateSubsectionOrderByIndex,
253299
]);
254300

255301
return (

src/course-outline/CourseOutline.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,14 @@ const CourseOutline = () => {
7979
restoreSectionList,
8080
setSections,
8181
updateSectionOrderByIndex,
82+
updateSubsectionOrderByIndex,
8283
} = useCourseAuthoringContext();
8384

8485
const {
8586
courseName,
8687
savingStatus,
8788
statusBarData,
8889
courseActions,
89-
sectionsList,
9090
isCustomRelativeDatesActive,
9191
isLoading,
9292
isLoadingDenied,
@@ -172,26 +172,6 @@ const CourseOutline = () => {
172172
const enableProctoredExams = useSelector(getProctoredExamsFlag);
173173
const enableTimedExams = useSelector(getTimedExamsFlag);
174174

175-
/**
176-
* Uses details from move information and moves subsection
177-
*/
178-
const updateSubsectionOrderByIndex = (section: XBlock, moveDetails) => {
179-
const { fn, args, sectionId } = moveDetails;
180-
if (!args) {
181-
return;
182-
}
183-
const [sectionsCopy, newSubsections] = fn(...args);
184-
if (newSubsections && sectionId) {
185-
setSections(sectionsCopy);
186-
handleSubsectionDragAndDrop(
187-
sectionId,
188-
section.id,
189-
newSubsections.map(subsection => subsection.id),
190-
restoreSectionList,
191-
);
192-
}
193-
};
194-
195175
/**
196176
* Uses details from move information and moves unit
197177
*/
@@ -215,10 +195,6 @@ const CourseOutline = () => {
215195
}
216196
};
217197

218-
useEffect(() => {
219-
setSections(sectionsList);
220-
}, [sectionsList]);
221-
222198
if (isLoading) {
223199
// eslint-disable-next-line react/jsx-no-useless-fragment
224200
return (
@@ -294,7 +270,7 @@ const CourseOutline = () => {
294270
isSectionsExpanded={isSectionsExpanded}
295271
headerNavigationsActions={headerNavigationsActions}
296272
isDisabledReindexButton={isDisabledReindexButton}
297-
hasSections={Boolean(sectionsList.length)}
273+
hasSections={Boolean(sections.length)}
298274
courseActions={courseActions}
299275
errors={errors}
300276
sections={sections}
@@ -324,7 +300,7 @@ const CourseOutline = () => {
324300
<div>
325301
{showNewActionsBar && (
326302
<ActionRow className="mt-3">
327-
{Boolean(sectionsList.length) && (
303+
{Boolean(sections.length) && (
328304
<Button
329305
variant="outline-primary"
330306
id="expand-collapse-all-button"

src/course-outline/hooks.jsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const useCourseOutline = ({ courseId }) => {
6666
handleDuplicateSubsectionSubmit,
6767
handleDuplicateUnitSubmit,
6868
handleSectionDragAndDrop,
69+
handleSubsectionDragAndDrop,
6970
} = useCourseAuthoringContext();
7071
const { selectedContainerState, clearSelection } = useOutlineSidebarContext();
7172

@@ -308,20 +309,6 @@ const useCourseOutline = ({ courseId }) => {
308309
dispatch(dismissNotificationQuery(`${getConfig().STUDIO_BASE_URL}${notificationDismissUrl}`));
309310
};
310311

311-
const handleSubsectionDragAndDrop = (
312-
sectionId,
313-
prevSectionId,
314-
subsectionListIds,
315-
restoreSectionList,
316-
) => {
317-
dispatch(setSubsectionOrderListQuery(
318-
sectionId,
319-
prevSectionId,
320-
subsectionListIds,
321-
restoreSectionList,
322-
));
323-
};
324-
325312
const handleUnitDragAndDrop = (
326313
sectionId,
327314
prevSectionId,

src/course-outline/outline-sidebar/OutlineSidebarContext.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ interface OutlineSidebarContextData {
3737
toggle: () => void;
3838
selectedContainerState?: SelectionState;
3939
setSelectedContainerState: (selectedContainerState?: SelectionState) => void;
40-
openContainerInfoSidebar: (containerId: string, subsectionId?: string, sectionId?: string, index?: number) => void;
40+
openContainerInfoSidebar: (
41+
containerId: string,
42+
subsectionId?: string,
43+
sectionId?: string,
44+
index?: number,
45+
sectionIndex?: number,
46+
) => void;
4147
clearSelection: () => void;
4248
/** Stores last section that allows adding subsections inside it. */
4349
lastEditableSection?: XBlock;
@@ -124,9 +130,18 @@ export const OutlineSidebarProvider = ({ children }: { children?: React.ReactNod
124130
subsectionId?: string,
125131
sectionId?: string,
126132
index?: number,
133+
sectionIndex?: number,
127134
) => {
128135
if (isOutlineNewDesignEnabled()) {
129-
setSelectedContainerState({ currentId: containerId, subsectionId, sectionId, index });
136+
console.log("EEEEEEEEEEEEEEe");
137+
console.log(sectionIndex);
138+
setSelectedContainerState({
139+
currentId: containerId,
140+
subsectionId,
141+
sectionId,
142+
index,
143+
sectionIndex,
144+
});
130145
setCurrentPageKey('info');
131146
}
132147
}, [setSelectedContainerState, setCurrentPageKey]);

src/course-outline/outline-sidebar/info-sidebar/InfoSidebar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const InfoSidebar = () => {
2929
<SubsectionSidebar
3030
subsectionId={selectedContainerState.currentId}
3131
index={selectedContainerState.index}
32+
sectionIndex={selectedContainerState.sectionIndex}
3233
/>
3334
);
3435
case ContainerType.Vertical:

src/course-outline/outline-sidebar/info-sidebar/SectionInfoSidebar.tsx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const SectionSidebar = ({ sectionId, index }: Props) => {
3030
sections,
3131
updateSectionOrderByIndex,
3232
} = useCourseAuthoringContext();
33-
const { clearSelection } = useOutlineSidebarContext();
33+
const { clearSelection, selectedContainerState, setSelectedContainerState } = useOutlineSidebarContext();
3434

3535
const handlePublish = () => {
3636
if (sectionData?.hasChanges) {
@@ -45,17 +45,12 @@ export const SectionSidebar = ({ sectionId, index }: Props) => {
4545
return <Loading />;
4646
}
4747

48-
const handleMoveUp = () => {
49-
if (index) {
50-
updateSectionOrderByIndex(index, index - 1);
48+
const handleMove = (step: number) => {
49+
if (index !== undefined) {
50+
updateSectionOrderByIndex(index, index + step);
51+
setSelectedContainerState(selectedContainerState ? { ...selectedContainerState, index: index + step } : undefined);
5152
}
52-
}
53-
54-
const handleMoveDown = () => {
55-
if (index) {
56-
updateSectionOrderByIndex(index, index + 1);
57-
}
58-
}
53+
};
5954

6055
return (
6156
<>
@@ -68,8 +63,8 @@ export const SectionSidebar = ({ sectionId, index }: Props) => {
6863
index: index ?? -1,
6964
canMoveItem: canMoveSection(sections),
7065
onClickDuplicate: handleDuplicateSectionSubmit,
71-
onClickMoveUp: handleMoveUp,
72-
onClickMoveDown: handleMoveDown,
66+
onClickMoveUp: () => handleMove(-1),
67+
onClickMoveDown: () => handleMove(1),
7368
onClickUnlink: () => {},
7469
onClickDelete: () => {},
7570
onClickViewLibrary: () => {},

0 commit comments

Comments
 (0)