From 92334e942ea33da612ee7c0a34dd2711d5b9ee71 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 14 Nov 2024 10:50:52 +0530 Subject: [PATCH 01/10] feat: preview library block changes --- src/course-unit/CourseUnit.jsx | 2 + src/course-unit/constants.js | 1 + src/course-unit/preview-changes/index.tsx | 66 +++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/course-unit/preview-changes/index.tsx diff --git a/src/course-unit/CourseUnit.jsx b/src/course-unit/CourseUnit.jsx index b235e832b9..4c54d6775e 100644 --- a/src/course-unit/CourseUnit.jsx +++ b/src/course-unit/CourseUnit.jsx @@ -36,6 +36,7 @@ import TagsSidebarControls from '../content-tags-drawer/tags-sidebar-controls'; import { PasteNotificationAlert } from './clipboard'; import XBlockContainerIframe from './xblock-container-iframe'; import MoveModal from './move-modal'; +import PreviewLibraryXBlockChanges from './preview-changes'; const CourseUnit = ({ courseId }) => { const { blockId } = useParams(); @@ -200,6 +201,7 @@ const CourseUnit = ({ courseId }) => { closeModal={closeMoveModal} courseId={courseId} /> + diff --git a/src/course-unit/constants.js b/src/course-unit/constants.js index ebadb310b4..f63490530b 100644 --- a/src/course-unit/constants.js +++ b/src/course-unit/constants.js @@ -52,6 +52,7 @@ export const messageTypes = { videoFullScreen: 'plugin.videoFullScreen', refreshXBlock: 'refreshXBlock', showMoveXBlockModal: 'showMoveXBlockModal', + showXBlockLibraryChangesPreview: 'showXBlockLibraryChangesPreview', }; export const IFRAME_FEATURE_POLICY = ( diff --git a/src/course-unit/preview-changes/index.tsx b/src/course-unit/preview-changes/index.tsx new file mode 100644 index 0000000000..f2cb82ed1a --- /dev/null +++ b/src/course-unit/preview-changes/index.tsx @@ -0,0 +1,66 @@ +import { ActionRow, Button, ModalDialog, useToggle } from "@openedx/paragon"; +import { useCallback } from "react"; +import { useEventListener } from "../../generic/hooks"; +import { messageTypes } from "../constants"; + +interface LibraryChangesMessageData { + downstreamBlockId: string, + courseAuthoringMfeUrl: string, + upstreamBlockId: string, + upstreamBlockVersionSynced: number, +} + +const PreviewLibraryXBlockChanges = () => { + const [isModalOpen, openModal, closeModal] = useToggle(false); + + const receiveMessage = useCallback(({ data }: { data: { + payload: LibraryChangesMessageData; + type: string; + } }) => { + const { payload, type } = data; + + if (type === messageTypes.showXBlockLibraryChangesPreview) { + openModal(); + } + }, [openModal]); + + useEventListener('message', receiveMessage); + + return ( + + + + Preview changes + + + + Preview Body + + + + + + + Cancel + + + + + ) +} + +export default PreviewLibraryXBlockChanges; From f77235cad45983a8c9199705d46b26f80c5dcedd Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 14 Nov 2024 18:28:18 +0530 Subject: [PATCH 02/10] refactor: simplify loading state in delete modal --- src/generic/delete-modal/DeleteModal.jsx | 29 ++++++------------- .../ComponentAdvancedAssets.tsx | 1 - .../components/CollectionCard.tsx | 1 - .../library-info/LibraryPublishStatus.tsx | 25 +++++++--------- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/src/generic/delete-modal/DeleteModal.jsx b/src/generic/delete-modal/DeleteModal.jsx index 52bbedcc1b..35936e4ebd 100644 --- a/src/generic/delete-modal/DeleteModal.jsx +++ b/src/generic/delete-modal/DeleteModal.jsx @@ -3,11 +3,11 @@ import { ActionRow, Button, AlertModal, - StatefulButton, } from '@openedx/paragon'; import { useIntl } from '@edx/frontend-platform/i18n'; import messages from './messages'; +import LoadingButton from '../loading-button'; const DeleteModal = ({ category, @@ -17,16 +17,13 @@ const DeleteModal = ({ title, description, variant, - btnState, - btnDefaultLabel, - btnPendingLabel, + btnLabel, }) => { const intl = useIntl(); const modalTitle = title || intl.formatMessage(messages.title, { category }); const modalDescription = description || intl.formatMessage(messages.description, { category }); - const defaultBtnLabel = btnDefaultLabel || intl.formatMessage(messages.deleteButton); - const pendingBtnLabel = btnPendingLabel || intl.formatMessage(messages.pendingDeleteButton); + const defaultBtnLabel = btnLabel || intl.formatMessage(messages.deleteButton); return ( {intl.formatMessage(messages.cancelButton)} - { + onClick={async (e) => { e.preventDefault(); e.stopPropagation(); - onDeleteSubmit(); - }} - labels={{ - default: defaultBtnLabel, - pending: pendingBtnLabel, + await onDeleteSubmit(); }} + label={defaultBtnLabel} /> )} @@ -72,9 +65,7 @@ DeleteModal.defaultProps = { title: '', description: '', variant: 'default', - btnState: 'default', - btnDefaultLabel: '', - btnPendingLabel: '', + btnLabel: '', }; DeleteModal.propTypes = { @@ -85,9 +76,7 @@ DeleteModal.propTypes = { title: PropTypes.string, description: PropTypes.string, variant: PropTypes.string, - btnState: PropTypes.string, - btnDefaultLabel: PropTypes.string, - btnPendingLabel: PropTypes.string, + btnLabel: PropTypes.string, }; export default DeleteModal; diff --git a/src/library-authoring/component-info/ComponentAdvancedAssets.tsx b/src/library-authoring/component-info/ComponentAdvancedAssets.tsx index a5812d9925..b9ea9ba567 100644 --- a/src/library-authoring/component-info/ComponentAdvancedAssets.tsx +++ b/src/library-authoring/component-info/ComponentAdvancedAssets.tsx @@ -92,7 +92,6 @@ export const ComponentAdvancedAssets: React.FC> = () => { title={intl.formatMessage(messages.advancedDetailsAssetsDeleteFileTitle)} description={`Are you sure you want to delete ${filePathToDelete}?`} onDeleteSubmit={deleteFile} - btnState="default" /> ); diff --git a/src/library-authoring/components/CollectionCard.tsx b/src/library-authoring/components/CollectionCard.tsx index c7c5164f62..ed79d7c2ea 100644 --- a/src/library-authoring/components/CollectionCard.tsx +++ b/src/library-authoring/components/CollectionCard.tsx @@ -97,7 +97,6 @@ const CollectionMenu = ({ collectionHit } : CollectionMenuProps) => { collectionTitle: collectionHit.displayName, })} onDeleteSubmit={deleteCollection} - btnState={confirmBtnState} /> ); diff --git a/src/library-authoring/library-info/LibraryPublishStatus.tsx b/src/library-authoring/library-info/LibraryPublishStatus.tsx index 2498a10241..875f117ad1 100644 --- a/src/library-authoring/library-info/LibraryPublishStatus.tsx +++ b/src/library-authoring/library-info/LibraryPublishStatus.tsx @@ -13,7 +13,6 @@ const LibraryPublishStatus = () => { const intl = useIntl(); const { libraryData, readOnly } = useLibraryContext(); const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useToggle(false); - const [confirmBtnState, setConfirmBtnState] = useState('default'); const commitLibraryChanges = useCommitLibraryChanges(); const revertLibraryChanges = useRevertLibraryChanges(); @@ -30,18 +29,16 @@ const LibraryPublishStatus = () => { } }, [libraryData]); - const revert = useCallback(() => { + const revert = useCallback(async () => { if (libraryData) { - setConfirmBtnState('pending'); - revertLibraryChanges.mutateAsync(libraryData.id) - .then(() => { - showToast(intl.formatMessage(messages.revertSuccessMsg)); - }).catch(() => { - showToast(intl.formatMessage(messages.revertErrorMsg)); - }).finally(() => { - setConfirmBtnState('default'); - closeConfirmModal(); - }); + try { + await revertLibraryChanges.mutateAsync(libraryData.id); + showToast(intl.formatMessage(messages.revertSuccessMsg)); + } catch (e) { + showToast(intl.formatMessage(messages.revertErrorMsg)); + } finally { + closeConfirmModal(); + } } }, [libraryData]); @@ -63,9 +60,7 @@ const LibraryPublishStatus = () => { title={intl.formatMessage(messages.discardChangesTitle)} description={intl.formatMessage(messages.discardChangesDescription)} onDeleteSubmit={revert} - btnState={confirmBtnState} - btnDefaultLabel={intl.formatMessage(messages.discardChangesDefaultBtnLabel)} - btnPendingLabel={intl.formatMessage(messages.discardChangesDefaultBtnLabel)} + btnLabel={intl.formatMessage(messages.discardChangesDefaultBtnLabel)} /> ); From c8ead640f5a0efe809db4787e974fd0ca881a8c3 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 14 Nov 2024 18:33:08 +0530 Subject: [PATCH 03/10] fixup! feat: preview library block changes --- src/course-unit/data/api.js | 19 ++++ src/course-unit/data/apiHooks.ts | 24 +++++ src/course-unit/preview-changes/index.tsx | 107 ++++++++++++++++++-- src/course-unit/preview-changes/messages.ts | 51 ++++++++++ 4 files changed, 192 insertions(+), 9 deletions(-) create mode 100644 src/course-unit/data/apiHooks.ts create mode 100644 src/course-unit/preview-changes/messages.ts diff --git a/src/course-unit/data/api.js b/src/course-unit/data/api.js index 7ede6e0236..0c7c53d27b 100644 --- a/src/course-unit/data/api.js +++ b/src/course-unit/data/api.js @@ -13,6 +13,7 @@ export const getCourseSectionVerticalApiUrl = (itemId) => `${getStudioBaseUrl()} export const getCourseVerticalChildrenApiUrl = (itemId) => `${getStudioBaseUrl()}/api/contentstore/v1/container/vertical/${itemId}/children`; export const getCourseOutlineInfoUrl = (courseId) => `${getStudioBaseUrl()}/course/${courseId}?format=concise`; export const postXBlockBaseApiUrl = () => `${getStudioBaseUrl()}/xblock/`; +export const acceptLibraryBlockChangesUrl = (blockId) => `${getStudioBaseUrl()}/api/contentstore/v2/downstreams/${blockId}/sync`; /** * Get course unit. @@ -206,3 +207,21 @@ export async function patchUnitItem(sourceLocator, targetParentLocator) { return camelCaseObject(data); } + +/** + * Accept the changes from upstream library block in course + * @param {string} blockId - The ID of the item to be updated from library. + */ +export async function acceptLibraryBlockChanges(blockId) { + await getAuthenticatedHttpClient() + .post(acceptLibraryBlockChangesUrl(blockId)); +} + +/** + * Ignore the changes from upstream library block in course + * @param {string} blockId - The ID of the item to be updated from library. + */ +export async function ignoreLibraryBlockChanges(blockId) { + await getAuthenticatedHttpClient() + .delete(acceptLibraryBlockChangesUrl(blockId)); +} diff --git a/src/course-unit/data/apiHooks.ts b/src/course-unit/data/apiHooks.ts new file mode 100644 index 0000000000..3c77bbe87f --- /dev/null +++ b/src/course-unit/data/apiHooks.ts @@ -0,0 +1,24 @@ +import { useMutation } from '@tanstack/react-query'; + +import { acceptLibraryBlockChanges, ignoreLibraryBlockChanges } from './api'; + +/** + * Hook that provides a "mutation" that can be used to accept library block changes. + */ +// eslint-disable-next-line import/prefer-default-export +export const useAcceptLibraryBlockChanges = () => { + return useMutation({ + mutationFn: acceptLibraryBlockChanges, + }); +}; + +/** + * Hook that provides a "mutation" that can be used to ignore library block changes. + */ +// eslint-disable-next-line import/prefer-default-export +export const useIgnoreLibraryBlockChanges = () => { + return useMutation({ + mutationFn: ignoreLibraryBlockChanges, + }); +}; + diff --git a/src/course-unit/preview-changes/index.tsx b/src/course-unit/preview-changes/index.tsx index f2cb82ed1a..84792917f6 100644 --- a/src/course-unit/preview-changes/index.tsx +++ b/src/course-unit/preview-changes/index.tsx @@ -1,17 +1,41 @@ +import { useCallback, useContext, useState } from "react"; import { ActionRow, Button, ModalDialog, useToggle } from "@openedx/paragon"; -import { useCallback } from "react"; +import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n'; + import { useEventListener } from "../../generic/hooks"; import { messageTypes } from "../constants"; +import CompareChangesWidget from "../../library-authoring/component-comparison/CompareChangesWidget"; +import { useAcceptLibraryBlockChanges, useIgnoreLibraryBlockChanges } from "../data/apiHooks"; +import { useIframe } from "../context/hooks"; +import DeleteModal from '../../generic/delete-modal/DeleteModal'; +import messages from './messages'; +import { ToastContext } from "../../generic/toast-context"; +import LoadingButton from "../../generic/loading-button"; interface LibraryChangesMessageData { + displayName: string, downstreamBlockId: string, courseAuthoringMfeUrl: string, upstreamBlockId: string, upstreamBlockVersionSynced: number, + isVertical: boolean, } const PreviewLibraryXBlockChanges = () => { + const intl = useIntl(); + const { showToast } = useContext(ToastContext); + + // Main preview library modal toggle. const [isModalOpen, openModal, closeModal] = useToggle(false); + // ignore changes confirmation modal toggle. + const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useToggle(false); + + const [blockData, setBlockData] = useState(undefined); + + const acceptChangesMutation = useAcceptLibraryBlockChanges(); + const ignoreChangesMutation = useIgnoreLibraryBlockChanges(); + + const { sendMessageToIframe } = useIframe(); const receiveMessage = useCallback(({ data }: { data: { payload: LibraryChangesMessageData; @@ -20,12 +44,64 @@ const PreviewLibraryXBlockChanges = () => { const { payload, type } = data; if (type === messageTypes.showXBlockLibraryChangesPreview) { + setBlockData(payload); openModal(); } }, [openModal]); useEventListener('message', receiveMessage); + const getTitle = useCallback(() => { + if (blockData?.displayName) { + return blockData?.displayName; + } + if (blockData?.isVertical) { + return "Unit"; + } + return "Component"; + }, [blockData]); + + const getBody = useCallback(() => { + if (!blockData) { + return null; + } + return ( + + ); + }, [blockData]); + + const handleAcceptChanges = useCallback(async () => { + if (!blockData) { + return; + } + try { + await acceptChangesMutation.mutateAsync(blockData.downstreamBlockId); + sendMessageToIframe(messageTypes.refreshXBlock, null); + } catch (e) { + showToast(intl.formatMessage(messages.acceptChangesFailure)); + } finally { + closeModal(); + } + }, [blockData]); + + const handleIgnoreChanges = useCallback(async () => { + if (!blockData) { + return; + } + try { + await ignoreChangesMutation.mutateAsync(blockData.downstreamBlockId); + sendMessageToIframe(messageTypes.refreshXBlock, null); + } catch (e) { + showToast(intl.formatMessage(messages.ignoreChangesFailure)); + } finally { + closeModal(); + } + }, [blockData]); + return ( { > - Preview changes + - Preview Body + {getBody()} - + - Cancel + + ) } diff --git a/src/course-unit/preview-changes/messages.ts b/src/course-unit/preview-changes/messages.ts new file mode 100644 index 0000000000..5be6788b12 --- /dev/null +++ b/src/course-unit/preview-changes/messages.ts @@ -0,0 +1,51 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + title: { + id: 'authoring.course-unit.preview-changes.modal-title', + defaultMessage: 'Preview changes: {blockTitle}', + description: 'Preview changes modal title text', + }, + acceptChangesBtn: { + id: 'authoring.course-unit.preview-changes.accept-changes-btn', + defaultMessage: 'Accept changes', + description: 'Preview changes modal accept button text.', + }, + acceptChangesFailure: { + id: 'authoring.course-unit.preview-changes.accept-changes-failure', + defaultMessage: 'Failed to update component', + description: 'Toast message to display when accepting changes call fails', + }, + ignoreChangesBtn: { + id: 'authoring.course-unit.preview-changes.accept-ignore-btn', + defaultMessage: 'Ignore changes', + description: 'Preview changes modal ignore button text.', + }, + ignoreChangesFailure: { + id: 'authoring.course-unit.preview-changes.ignore-changes-failure', + defaultMessage: 'Failed to ignore changes', + description: 'Toast message to display when ignore changes call fails', + }, + cancelBtn: { + id: 'authoring.course-unit.preview-changes.cancel-btn', + defaultMessage: 'Cancel', + description: 'Preview changes modal cancel button text.', + }, + confirmationTitle: { + id: 'authoring.course-unit.preview-changes.confirmation-dialog-title', + defaultMessage: 'Ignore these changes?', + description: 'Preview changes confirmation dialog title when user clicks on ignore changes.', + }, + confirmationDescription: { + id: 'authoring.course-unit.preview-changes.confirmation-dialog-description', + defaultMessage: 'Would you like to permanently ignore this updated version? If so, you won\'t be able to update this until a newer version is published (in the library).', + description: 'Preview changes confirmation dialog description text when user clicks on ignore changes.', + }, + confirmationConfirmBtn: { + id: 'authoring.course-unit.preview-changes.confirmation-dialog-confirm-btn', + defaultMessage: 'Ignore', + description: 'Preview changes confirmation dialog confirm button text when user clicks on ignore changes.', + }, +}); + +export default messages; From 0cd11d805f23be5480ed111b0fce22624b574a67 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 14 Nov 2024 18:47:21 +0530 Subject: [PATCH 04/10] refactor: simpify accept and ignore library block changes --- src/course-unit/preview-changes/index.tsx | 26 +++++++---------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/course-unit/preview-changes/index.tsx b/src/course-unit/preview-changes/index.tsx index 84792917f6..ea1eba269a 100644 --- a/src/course-unit/preview-changes/index.tsx +++ b/src/course-unit/preview-changes/index.tsx @@ -74,29 +74,19 @@ const PreviewLibraryXBlockChanges = () => { ); }, [blockData]); - const handleAcceptChanges = useCallback(async () => { + const updateAndRefresh = useCallback(async (accept: boolean) => { if (!blockData) { return; } - try { - await acceptChangesMutation.mutateAsync(blockData.downstreamBlockId); - sendMessageToIframe(messageTypes.refreshXBlock, null); - } catch (e) { - showToast(intl.formatMessage(messages.acceptChangesFailure)); - } finally { - closeModal(); - } - }, [blockData]); - const handleIgnoreChanges = useCallback(async () => { - if (!blockData) { - return; - } + const mutation = accept ? acceptChangesMutation: ignoreChangesMutation; + let failureMsg = accept ? messages.acceptChangesFailure: messages.ignoreChangesFailure; + try { - await ignoreChangesMutation.mutateAsync(blockData.downstreamBlockId); + await mutation.mutateAsync(blockData.downstreamBlockId); sendMessageToIframe(messageTypes.refreshXBlock, null); } catch (e) { - showToast(intl.formatMessage(messages.ignoreChangesFailure)); + showToast(intl.formatMessage(failureMsg)); } finally { closeModal(); } @@ -125,7 +115,7 @@ const PreviewLibraryXBlockChanges = () => { updateAndRefresh(true)} label={intl.formatMessage(messages.acceptChangesBtn)} /> { e.preventDefault(); e.stopPropagation(); From 9de6738df56a0dabe914e50327d8e44b07a139ed Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Tue, 19 Nov 2024 11:36:35 +0530 Subject: [PATCH 09/10] feat: display new title in preview modal --- .../preview-changes/index.test.tsx | 10 +++++++++ src/course-unit/preview-changes/index.tsx | 22 ++++++++++++------- src/course-unit/preview-changes/messages.ts | 5 +++++ src/library-authoring/data/apiHooks.ts | 7 +++--- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/course-unit/preview-changes/index.test.tsx b/src/course-unit/preview-changes/index.test.tsx index f603181a1c..235560820f 100644 --- a/src/course-unit/preview-changes/index.test.tsx +++ b/src/course-unit/preview-changes/index.test.tsx @@ -13,6 +13,7 @@ import { messageTypes } from '../constants'; import { IframeProvider } from '../context/iFrameContext'; import { libraryBlockChangesUrl } from '../data/api'; import { ToastActionData } from '../../generic/toast-context'; +import { getLibraryBlockMetadataUrl } from '../../library-authoring/data/api'; const usageKey = 'some-id'; const defaultEventData: LibraryChangesMessageData = { @@ -78,6 +79,15 @@ describe('', () => { expect(await screen.findByText('Preview changes: Component')).toBeInTheDocument(); }); + it('renders both new and old title if they are different', async () => { + axiosMock.onGet(getLibraryBlockMetadataUrl(defaultEventData.upstreamBlockId)).reply(200, { + displayName: 'New test block', + }); + render(); + + expect(await screen.findByText('Preview changes: Test block -> New test block')).toBeInTheDocument(); + }); + it('accept changes works', async () => { axiosMock.onPost(libraryBlockChangesUrl(usageKey)).reply(200, {}); render(); diff --git a/src/course-unit/preview-changes/index.tsx b/src/course-unit/preview-changes/index.tsx index c0eb8cd7fd..dc39755183 100644 --- a/src/course-unit/preview-changes/index.tsx +++ b/src/course-unit/preview-changes/index.tsx @@ -14,6 +14,7 @@ import messages from './messages'; import { ToastContext } from '../../generic/toast-context'; import LoadingButton from '../../generic/loading-button'; import Loading from '../../generic/Loading'; +import { useLibraryBlockMetadata } from '../../library-authoring/data/apiHooks'; export interface LibraryChangesMessageData { displayName: string, @@ -36,6 +37,7 @@ const PreviewLibraryXBlockChanges = () => { const acceptChangesMutation = useAcceptLibraryBlockChanges(); const ignoreChangesMutation = useIgnoreLibraryBlockChanges(); + const { data: componentMetadata } = useLibraryBlockMetadata(blockData?.upstreamBlockId); const { sendMessageToIframe } = useIframe(); @@ -54,16 +56,20 @@ const PreviewLibraryXBlockChanges = () => { useEventListener('message', receiveMessage); const getTitle = useCallback(() => { - if (blockData?.displayName) { - return intl.formatMessage(messages.title, { - blockTitle: blockData?.displayName, - }); + const oldName = blockData?.displayName; + const newName = componentMetadata?.displayName; + + if (!oldName) { + if (blockData?.isVertical) { + return intl.formatMessage(messages.defaultUnitTitle); + } + return intl.formatMessage(messages.defaultComponentTitle); } - if (blockData?.isVertical) { - return intl.formatMessage(messages.defaultUnitTitle); + if (oldName === newName || !newName) { + return intl.formatMessage(messages.title, { blockTitle: oldName }); } - return intl.formatMessage(messages.defaultComponentTitle); - }, [blockData]); + return intl.formatMessage(messages.diffTitle, { oldName, newName }); + }, [blockData, componentMetadata]); const getBody = useCallback(() => { if (!blockData) { diff --git a/src/course-unit/preview-changes/messages.ts b/src/course-unit/preview-changes/messages.ts index 4a35b0a86b..6b0d778c26 100644 --- a/src/course-unit/preview-changes/messages.ts +++ b/src/course-unit/preview-changes/messages.ts @@ -6,6 +6,11 @@ const messages = defineMessages({ defaultMessage: 'Preview changes: {blockTitle}', description: 'Preview changes modal title text', }, + diffTitle: { + id: 'authoring.course-unit.preview-changes.modal-diff-title', + defaultMessage: 'Preview changes: {oldName} -> {newName}', + description: 'Preview changes modal title text', + }, defaultUnitTitle: { id: 'authoring.course-unit.preview-changes.modal-default-unit-title', defaultMessage: 'Preview changes: Unit', diff --git a/src/library-authoring/data/apiHooks.ts b/src/library-authoring/data/apiHooks.ts index e1ab38f1f5..09151a4602 100644 --- a/src/library-authoring/data/apiHooks.ts +++ b/src/library-authoring/data/apiHooks.ts @@ -285,10 +285,11 @@ export const useLibraryPasteClipboard = () => { }); }; -export const useLibraryBlockMetadata = (usageId: string) => ( +export const useLibraryBlockMetadata = (usageId: string | undefined) => ( useQuery({ - queryKey: xblockQueryKeys.componentMetadata(usageId), - queryFn: () => getLibraryBlockMetadata(usageId), + queryKey: xblockQueryKeys.componentMetadata(usageId!), + queryFn: () => getLibraryBlockMetadata(usageId!), + enabled: !!usageId, }) ); From a065191da94fbaf69cc4d8e1b32d8cce444c344e Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 21 Nov 2024 11:18:54 +0530 Subject: [PATCH 10/10] fix: preview modal height issues --- src/course-unit/CourseUnit.scss | 1 + src/course-unit/preview-changes/index.scss | 4 ++++ src/library-authoring/LibraryBlock/LibraryBlock.tsx | 8 ++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/course-unit/preview-changes/index.scss diff --git a/src/course-unit/CourseUnit.scss b/src/course-unit/CourseUnit.scss index 3ada01ca2f..a2d6124ba3 100644 --- a/src/course-unit/CourseUnit.scss +++ b/src/course-unit/CourseUnit.scss @@ -4,6 +4,7 @@ @import "./sidebar/Sidebar"; @import "./header-title/HeaderTitle"; @import "./move-modal"; +@import "./preview-changes"; .course-unit__alert { margin-bottom: 1.75rem; diff --git a/src/course-unit/preview-changes/index.scss b/src/course-unit/preview-changes/index.scss new file mode 100644 index 0000000000..b6749c9214 --- /dev/null +++ b/src/course-unit/preview-changes/index.scss @@ -0,0 +1,4 @@ +.lib-preview-xblock-changes-modal { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} diff --git a/src/library-authoring/LibraryBlock/LibraryBlock.tsx b/src/library-authoring/LibraryBlock/LibraryBlock.tsx index b76e2b1aea..4397090edd 100644 --- a/src/library-authoring/LibraryBlock/LibraryBlock.tsx +++ b/src/library-authoring/LibraryBlock/LibraryBlock.tsx @@ -22,7 +22,7 @@ interface LibraryBlockProps { */ export const LibraryBlock = ({ onBlockNotification, usageKey, version }: LibraryBlockProps) => { const iframeRef = useRef(null); - const [iFrameHeight, setIFrameHeight] = useState(600); + const [iFrameHeight, setIFrameHeight] = useState(50); const studioBaseUrl = getConfig().STUDIO_BASE_URL; const intl = useIntl(); @@ -59,6 +59,10 @@ export const LibraryBlock = ({ onBlockNotification, usageKey, version }: Library // Messages are the only way that the code in the IFrame can communicate // with the surrounding UI. window.addEventListener('message', receivedWindowMessage); + if (window.self !== window.top) { + // This component is loaded inside an iframe. + setIFrameHeight(86); + } return () => { window.removeEventListener('message', receivedWindowMessage); @@ -69,7 +73,7 @@ export const LibraryBlock = ({ onBlockNotification, usageKey, version }: Library return (