Skip to content

Commit 739668d

Browse files
committed
feat: add resetXBlockPublishState functionality to manage publish state after changes
1 parent aefb908 commit 739668d

File tree

5 files changed

+72
-3
lines changed

5 files changed

+72
-3
lines changed

src/course-unit/CourseUnit.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const CourseUnit = ({ courseId }) => {
7171
handleCloseXBlockMovedAlert,
7272
handleNavigateToTargetUnit,
7373
addComponentTemplateData,
74+
resetXBlockPublishState,
7475
} = useCourseUnit({ courseId, blockId });
7576
const layoutGrid = useLayoutGrid(unitCategory, isUnitLibraryType);
7677

@@ -213,6 +214,7 @@ const CourseUnit = ({ courseId }) => {
213214
unitXBlockActions={unitXBlockActions}
214215
courseVerticalChildren={courseVerticalChildren.children}
215216
handleConfigureSubmit={handleConfigureSubmit}
217+
resetXBlockPublishState={resetXBlockPublishState}
216218
/>
217219
{!readOnly && (
218220
<AddComponent

src/course-unit/CourseUnit.test.jsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,4 +2304,59 @@ describe('<CourseUnit />', () => {
23042304
// Does not render the "Add Components" section
23052305
expect(screen.queryByText(addComponentMessages.title.defaultMessage)).not.toBeInTheDocument();
23062306
});
2307+
2308+
it('resets XBlock publish state after discarding changes', async () => {
2309+
render(<RootWrapper />);
2310+
let courseUnitSidebar;
2311+
let discardChangesBtn;
2312+
2313+
await waitFor(() => {
2314+
courseUnitSidebar = screen.getByTestId('course-unit-sidebar');
2315+
// Ensure we are in the draft/unpublished state
2316+
expect(within(courseUnitSidebar)
2317+
.getByText(sidebarMessages.sidebarTitleDraftUnpublishedChanges.defaultMessage)).toBeInTheDocument();
2318+
discardChangesBtn = within(courseUnitSidebar)
2319+
.queryByRole('button', { name: sidebarMessages.actionButtonDiscardChangesTitle.defaultMessage });
2320+
expect(discardChangesBtn).toBeInTheDocument();
2321+
userEvent.click(discardChangesBtn);
2322+
});
2323+
2324+
// Confirm discard in modal
2325+
const modalNotification = await screen.findByRole('dialog');
2326+
const actionBtn = within(modalNotification)
2327+
.getByRole('button', { name: sidebarMessages.modalDiscardUnitChangesActionButtonText.defaultMessage });
2328+
userEvent.click(actionBtn);
2329+
2330+
// Mock API responses for discard
2331+
axiosMock
2332+
.onPost(getXBlockBaseApiUrl(blockId), {
2333+
publish: PUBLISH_TYPES.discardChanges,
2334+
})
2335+
.reply(200, { dummy: 'value' });
2336+
axiosMock
2337+
.onGet(getCourseSectionVerticalApiUrl(blockId))
2338+
.reply(200, {
2339+
...courseSectionVerticalMock,
2340+
xblock_info: {
2341+
...courseSectionVerticalMock.xblock_info,
2342+
published: true,
2343+
has_changes: false,
2344+
},
2345+
});
2346+
2347+
await executeThunk(editCourseUnitVisibilityAndData(
2348+
blockId,
2349+
PUBLISH_TYPES.discardChanges,
2350+
true,
2351+
), store.dispatch);
2352+
2353+
// Now the sidebar should reflect the published state (no draft/unpublished changes)
2354+
await waitFor(() => {
2355+
expect(within(courseUnitSidebar)
2356+
.getByText(sidebarMessages.sidebarTitlePublishedNotYetReleased.defaultMessage)).toBeInTheDocument();
2357+
expect(
2358+
within(courseUnitSidebar).queryByRole('button', { name: sidebarMessages.actionButtonDiscardChangesTitle.defaultMessage })
2359+
).not.toBeInTheDocument();
2360+
});
2361+
});
23072362
});

src/course-unit/hooks.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
} from './data/selectors';
3838
import {
3939
changeEditTitleFormOpen,
40+
setXBlockPublishState,
4041
updateMovedXBlockParams,
4142
updateQueryPendingStatus,
4243
} from './data/slice';
@@ -162,6 +163,10 @@ export const useCourseUnit = ({ courseId, blockId }) => {
162163
const handleCloseXBlockMovedAlert = () => {
163164
dispatch(updateMovedXBlockParams({ isSuccess: false }));
164165
};
166+
167+
const resetXBlockPublishState = () => {
168+
dispatch(setXBlockPublishState(false));
169+
};
165170

166171
const handleNavigateToTargetUnit = () => {
167172
navigate(`/course/${courseId}/container/${movedXBlockParams.targetParentLocator}`);
@@ -248,6 +253,7 @@ export const useCourseUnit = ({ courseId, blockId }) => {
248253
handleNavigateToTargetUnit,
249254
addComponentTemplateData,
250255
setAddComponentTemplateData,
256+
resetXBlockPublishState,
251257
};
252258
};
253259

src/course-unit/xblock-container-iframe/index.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@ import { useIframeContent } from '../../generic/hooks/useIframeContent';
3737
import { useIframeMessages } from '../../generic/hooks/useIframeMessages';
3838
import VideoSelectorPage from '../../editors/VideoSelectorPage';
3939
import EditorPage from '../../editors/EditorPage';
40-
import { setXBlockPublishState } from '../data/slice';
4140

4241
const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
43-
courseId, blockId, unitXBlockActions, courseVerticalChildren, handleConfigureSubmit, isUnitVerticalType,
42+
courseId,
43+
blockId,
44+
unitXBlockActions,
45+
courseVerticalChildren,
46+
handleConfigureSubmit,
47+
isUnitVerticalType,
48+
resetXBlockPublishState,
4449
}) => {
4550
const intl = useIntl();
4651
const dispatch = useDispatch();
@@ -76,7 +81,7 @@ const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
7681
closeVideoSelectorModal();
7782
sendMessageToIframe(messageTypes.completeXBlockEditing, { locator: newBlockId });
7883
// This ensures the publish button is able
79-
dispatch(setXBlockPublishState(false));
84+
resetXBlockPublishState();
8085
}, [closeXBlockEditorModal, closeVideoSelectorModal, sendMessageToIframe, newBlockId]);
8186

8287
const handleEditXBlock = useCallback((type: string, id: string) => {

src/course-unit/xblock-container-iframe/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export interface XBlockContainerIframeProps {
4848
};
4949
courseVerticalChildren: Array<XBlockTypes>;
5050
handleConfigureSubmit: (XBlockId: string, ...args: any[]) => void;
51+
resetXBlockPublishState: () => void;
5152
}
5253

5354
export type UserPartitionInfoTypes = {

0 commit comments

Comments
 (0)