feat: [FC-0044] Unit page - display xblock components

This commit is contained in:
Ihor Romaniuk
2024-01-23 14:17:15 +01:00
committed by Adolfo R. Brandes
parent e4c3997d17
commit f8095e6670
33 changed files with 1050 additions and 38 deletions

View File

@@ -24,8 +24,11 @@ import { RequestStatus } from '../data/constants';
import SubHeader from '../generic/sub-header/SubHeader';
import ProcessingNotification from '../generic/processing-notification';
import InternetConnectionAlert from '../generic/internet-connection-alert';
import DeleteModal from '../generic/delete-modal/DeleteModal';
import AlertMessage from '../generic/alert-message';
import getPageHeadTitle from '../generic/utils';
import { getCurrentItem } from './data/selectors';
import { COURSE_BLOCK_NAMES } from './constants';
import HeaderNavigations from './header-navigations/HeaderNavigations';
import OutlineSideBar from './outline-sidebar/OutlineSidebar';
import StatusBar from './status-bar/StatusBar';
@@ -37,7 +40,6 @@ import HighlightsModal from './highlights-modal/HighlightsModal';
import EmptyPlaceholder from './empty-placeholder/EmptyPlaceholder';
import PublishModal from './publish-modal/PublishModal';
import ConfigureModal from './configure-modal/ConfigureModal';
import DeleteModal from './delete-modal/DeleteModal';
import PageAlerts from './page-alerts/PageAlerts';
import { useCourseOutline } from './hooks';
import messages from './messages';
@@ -115,6 +117,9 @@ const CourseOutline = ({ courseId }) => {
title: processingNotificationTitle,
} = useSelector(getProcessingNotification);
const { category } = useSelector(getCurrentItem);
const deleteCategory = COURSE_BLOCK_NAMES[category]?.name.toLowerCase();
const finalizeSectionOrder = () => (newSections) => {
initialSections = [...sectionsList];
handleSectionDragAndDrop(newSections.map(section => section.id), () => {
@@ -459,6 +464,7 @@ const CourseOutline = ({ courseId }) => {
onConfigureSubmit={handleConfigureItemSubmit}
/>
<DeleteModal
category={deleteCategory}
isOpen={isDeleteModalOpen}
close={closeDeleteModal}
onDeleteSubmit={handleDeleteItemSubmit}

View File

@@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { Container, Layout } from '@openedx/paragon';
import { Container, Layout, Stack } from '@openedx/paragon';
import { useIntl, injectIntl } from '@edx/frontend-platform/i18n';
import { ErrorAlert } from '@edx/frontend-lib-content-components';
@@ -13,6 +13,7 @@ import ProcessingNotification from '../generic/processing-notification';
import InternetConnectionAlert from '../generic/internet-connection-alert';
import Loading from '../generic/Loading';
import AddComponent from './add-component/AddComponent';
import CourseXBlock from './course-xblock/CourseXBlock';
import HeaderTitle from './header-title/HeaderTitle';
import Breadcrumbs from './breadcrumbs/Breadcrumbs';
import HeaderNavigations from './header-navigations/HeaderNavigations';
@@ -32,11 +33,13 @@ const CourseUnit = ({ courseId }) => {
isTitleEditFormOpen,
isErrorAlert,
isInternetConnectionAlertFailed,
unitXBlockActions,
handleTitleEditSubmit,
headerNavigationsActions,
handleTitleEdit,
handleInternetConnectionFailed,
handleCreateNewCourseXBlock,
courseVerticalChildren,
} = useCourseUnit({ courseId, blockId });
document.title = getPageHeadTitle('', unitTitle);
@@ -90,6 +93,18 @@ const CourseUnit = ({ courseId }) => {
xl={[{ span: 9 }, { span: 3 }]}
>
<Layout.Element>
<Stack gap={4} className="mb-4">
{courseVerticalChildren.children.map(({ name, blockId: id, shouldScroll }) => (
<CourseXBlock
id={id}
key={id}
title={name}
shouldScroll={shouldScroll}
unitXBlockActions={unitXBlockActions}
data-testid="course-xblock"
/>
))}
</Stack>
<AddComponent
blockId={blockId}
handleCreateNewCourseXBlock={handleCreateNewCourseXBlock}

View File

@@ -1,3 +1,4 @@
@import "./breadcrumbs/Breadcrumbs";
@import "./course-sequence/CourseSequence";
@import "./add-component/AddComponent";
@import "./course-xblock/CourseXblock";

View File

@@ -12,12 +12,14 @@ import { cloneDeep, set } from 'lodash';
import {
getCourseSectionVerticalApiUrl,
getCourseUnitApiUrl,
getCourseVerticalChildrenApiUrl,
getXBlockBaseApiUrl,
postXBlockBaseApiUrl,
} from './data/api';
import {
fetchCourseSectionVerticalData,
fetchCourseUnitQuery,
fetchCourseVerticalChildrenData,
} from './data/thunk';
import initializeStore from '../store';
import {
@@ -25,13 +27,17 @@ import {
courseSectionVerticalMock,
courseUnitIndexMock,
courseUnitMock,
courseVerticalChildrenMock,
} from './__mocks__';
import { executeThunk } from '../utils';
import CourseUnit from './CourseUnit';
import headerNavigationsMessages from './header-navigations/messages';
import headerTitleMessages from './header-title/messages';
import courseSequenceMessages from './course-sequence/messages';
import messages from './add-component/messages';
import deleteModalMessages from '../generic/delete-modal/messages';
import courseXBlockMessages from './course-xblock/messages';
import addComponentMessages from './add-component/messages';
let axiosMock;
let store;
@@ -75,6 +81,10 @@ describe('<CourseUnit />', () => {
.onGet(getCourseSectionVerticalApiUrl(blockId))
.reply(200, courseSectionVerticalMock);
await executeThunk(fetchCourseSectionVerticalData(blockId), store.dispatch);
axiosMock
.onGet(getCourseVerticalChildrenApiUrl(blockId))
.reply(200, courseVerticalChildrenMock);
await executeThunk(fetchCourseVerticalChildrenData(blockId), store.dispatch);
});
it('render CourseUnit component correctly', async () => {
@@ -169,7 +179,7 @@ describe('<CourseUnit />', () => {
await waitFor(() => {
const videoButton = getByRole('button', {
name: new RegExp(`${messages.buttonText.defaultMessage} Video`, 'i'),
name: new RegExp(`${addComponentMessages.buttonText.defaultMessage} Video`, 'i'),
});
userEvent.click(videoButton);
@@ -186,7 +196,7 @@ describe('<CourseUnit />', () => {
await waitFor(() => {
const problemButton = getByRole('button', {
name: new RegExp(`${messages.buttonText.defaultMessage} Problem`, 'i'),
name: new RegExp(`${addComponentMessages.buttonText.defaultMessage} Problem`, 'i'),
});
userEvent.click(problemButton);
@@ -291,7 +301,7 @@ describe('<CourseUnit />', () => {
await waitFor(() => {
const videoButton = getByRole('button', {
name: new RegExp(`${messages.buttonText.defaultMessage} Video`, 'i'),
name: new RegExp(`${addComponentMessages.buttonText.defaultMessage} Video`, 'i'),
});
userEvent.click(videoButton);
@@ -299,4 +309,73 @@ describe('<CourseUnit />', () => {
expect(mockedUsedNavigate).toHaveBeenCalledWith(`/course/${courseKey}/editor/video/${locator}`);
});
});
it('checks whether xblock is deleted when corresponding delete button is clicked', async () => {
axiosMock
.onDelete(getXBlockBaseApiUrl(courseVerticalChildrenMock.children[0].block_id))
.replyOnce(200, { dummy: 'value' });
const {
getByText,
getAllByLabelText,
getByRole,
getAllByTestId,
} = render(<RootWrapper />);
await waitFor(() => {
expect(getByText(unitDisplayName)).toBeInTheDocument();
const [xblockActionBtn] = getAllByLabelText(courseXBlockMessages.blockActionsDropdownAlt.defaultMessage);
userEvent.click(xblockActionBtn);
const deleteBtn = getByRole('button', { name: courseXBlockMessages.blockLabelButtonDelete.defaultMessage });
userEvent.click(deleteBtn);
expect(getByText(/Delete this component?/)).toBeInTheDocument();
const deleteConfirmBtn = getByRole('button', { name: deleteModalMessages.deleteButton.defaultMessage });
userEvent.click(deleteConfirmBtn);
expect(getAllByTestId('course-xblock')).toHaveLength(1);
});
});
it('checks whether xblock is duplicate when corresponding delete button is clicked', async () => {
axiosMock
.onPost(postXBlockBaseApiUrl({
parent_locator: blockId,
duplicate_source_locator: courseVerticalChildrenMock.children[0].block_id,
}))
.replyOnce(200, { locator: '1234567890' });
axiosMock
.onGet(getCourseVerticalChildrenApiUrl(blockId))
.reply(200, {
...courseVerticalChildrenMock,
children: [
...courseVerticalChildrenMock.children,
{
name: 'New Cloned XBlock',
block_id: '1234567890',
block_type: 'drag-and-drop-v2',
},
],
});
const {
getByText,
getAllByLabelText,
getAllByTestId,
} = render(<RootWrapper />);
await waitFor(() => {
expect(getByText(unitDisplayName)).toBeInTheDocument();
const [xblockActionBtn] = getAllByLabelText(courseXBlockMessages.blockActionsDropdownAlt.defaultMessage);
userEvent.click(xblockActionBtn);
const duplicateBtn = getByText(courseXBlockMessages.blockLabelButtonDuplicate.defaultMessage);
userEvent.click(duplicateBtn);
expect(getAllByTestId('course-xblock')).toHaveLength(3);
expect(getByText('New Cloned XBlock')).toBeInTheDocument();
});
});
});

View File

@@ -0,0 +1,15 @@
module.exports = {
children: [
{
name: 'Discussion',
block_id: 'block-v1:edX+L153+3T2023+type@discussion+block@fecd20842dd24f50bdc06643e791b013',
block_type: 'discussion',
},
{
name: 'Drag and Drop',
block_id: 'block-v1:edX+L153+3T2023+type@drag-and-drop-v2+block@b33cf1f6df4c41639659bc91132eeb02',
block_type: 'drag-and-drop-v2',
},
],
is_published: false,
};

View File

@@ -2,3 +2,4 @@ export { default as courseUnitIndexMock } from './courseUnitIndex';
export { default as courseSectionVerticalMock } from './courseSectionVertical';
export { default as courseUnitMock } from './courseUnit';
export { default as courseCreateXblockMock } from './courseCreateXblock';
export { default as courseVerticalChildrenMock } from './courseVerticalChildren';

View File

@@ -0,0 +1,104 @@
import { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import {
ActionRow, Card, Dropdown, Icon, IconButton, useToggle,
} from '@openedx/paragon';
import { EditOutline as EditIcon, MoreVert as MoveVertIcon } from '@openedx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';
import DeleteModal from '../../generic/delete-modal/DeleteModal';
import { scrollToElement } from '../../course-outline/utils';
import messages from './messages';
const CourseXBlock = ({
id, title, unitXBlockActions, shouldScroll, ...props
}) => {
const courseXBlockElementRef = useRef(null);
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useToggle(false);
const intl = useIntl();
const onXBlockDelete = () => {
unitXBlockActions.handleDelete(id);
closeDeleteModal();
};
useEffect(() => {
// if this item has been newly added, scroll to it.
if (courseXBlockElementRef.current && shouldScroll) {
scrollToElement(courseXBlockElementRef.current);
}
}, []);
return (
<div ref={courseXBlockElementRef} {...props}>
<Card className="mb-1">
<Card.Header
title={title}
actions={(
<ActionRow>
<IconButton
alt={intl.formatMessage(messages.blockAltButtonEdit)}
iconAs={EditIcon}
size="md"
onClick={() => {}}
/>
<Dropdown>
<Dropdown.Toggle
id={id}
as={IconButton}
src={MoveVertIcon}
alt={intl.formatMessage(messages.blockActionsDropdownAlt)}
size="sm"
iconAs={Icon}
/>
<Dropdown.Menu>
<Dropdown.Item>
{intl.formatMessage(messages.blockLabelButtonCopy)}
</Dropdown.Item>
<Dropdown.Item onClick={() => unitXBlockActions.handleDuplicate(id)}>
{intl.formatMessage(messages.blockLabelButtonDuplicate)}
</Dropdown.Item>
<Dropdown.Item>
{intl.formatMessage(messages.blockLabelButtonMove)}
</Dropdown.Item>
<Dropdown.Item>
{intl.formatMessage(messages.blockLabelButtonManageAccess)}
</Dropdown.Item>
<Dropdown.Item onClick={openDeleteModal}>
{intl.formatMessage(messages.blockLabelButtonDelete)}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<DeleteModal
category="component"
isOpen={isDeleteModalOpen}
close={closeDeleteModal}
onDeleteSubmit={onXBlockDelete}
/>
</ActionRow>
)}
size="md"
/>
<Card.Section>
<div className="w-100 bg-gray-100" style={{ height: 200 }} data-block-id={id} />
</Card.Section>
</Card>
</div>
);
};
CourseXBlock.defaultProps = {
shouldScroll: false,
};
CourseXBlock.propTypes = {
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
shouldScroll: PropTypes.bool,
unitXBlockActions: PropTypes.shape({
handleDelete: PropTypes.func,
handleDuplicate: PropTypes.func,
}).isRequired,
};
export default CourseXBlock;

View File

@@ -0,0 +1,108 @@
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { initializeMockApp } from '@edx/frontend-platform';
import { AppProvider } from '@edx/frontend-platform/react';
import { courseVerticalChildrenMock } from '../__mocks__';
import CourseXBlock from './CourseXBlock';
import deleteModalMessages from '../../generic/delete-modal/messages';
import messages from './messages';
let store;
const handleDeleteMock = jest.fn();
const handleDuplicateMock = jest.fn();
const xblockData = courseVerticalChildrenMock.children[0];
const unitXBlockActionsMock = {
handleDelete: handleDeleteMock,
handleDuplicate: handleDuplicateMock,
};
const renderComponent = () => render(
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseXBlock
id={xblockData.block_id}
title={xblockData.block_id}
unitXBlockActions={unitXBlockActionsMock}
shouldScroll={false}
/>
</IntlProvider>
</AppProvider>,
);
describe('<CourseXBlock />', () => {
beforeEach(async () => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
});
it('render CourseXBlock component correctly', async () => {
const { getByText, getByLabelText } = renderComponent();
await waitFor(() => {
expect(getByText(xblockData.block_id)).toBeInTheDocument();
expect(getByLabelText(messages.blockAltButtonEdit.defaultMessage)).toBeInTheDocument();
expect(getByLabelText(messages.blockActionsDropdownAlt.defaultMessage)).toBeInTheDocument();
});
});
it('render CourseXBlock component action dropdown correctly', async () => {
const { getByRole, getByLabelText } = renderComponent();
await waitFor(() => {
userEvent.click(getByLabelText(messages.blockActionsDropdownAlt.defaultMessage));
expect(getByRole('button', { name: messages.blockLabelButtonCopy.defaultMessage })).toBeInTheDocument();
expect(getByRole('button', { name: messages.blockLabelButtonDuplicate.defaultMessage })).toBeInTheDocument();
expect(getByRole('button', { name: messages.blockLabelButtonMove.defaultMessage })).toBeInTheDocument();
expect(getByRole('button', { name: messages.blockLabelButtonManageAccess.defaultMessage })).toBeInTheDocument();
expect(getByRole('button', { name: messages.blockLabelButtonDelete.defaultMessage })).toBeInTheDocument();
});
});
it('calls handleDuplicate when item is clicked', async () => {
const { getByText, getByLabelText } = renderComponent();
await waitFor(() => {
userEvent.click(getByLabelText(messages.blockActionsDropdownAlt.defaultMessage));
const duplicateBtn = getByText(messages.blockLabelButtonDuplicate.defaultMessage);
userEvent.click(duplicateBtn);
expect(handleDuplicateMock).toHaveBeenCalledTimes(1);
expect(handleDuplicateMock).toHaveBeenCalledWith(xblockData.block_id);
});
});
it('opens confirm delete modal and calls handleDelete when deleting was confirmed', async () => {
const { getByText, getByLabelText, getByRole } = renderComponent();
await waitFor(() => {
userEvent.click(getByLabelText(messages.blockActionsDropdownAlt.defaultMessage));
const deleteBtn = getByText(messages.blockLabelButtonDelete.defaultMessage);
userEvent.click(deleteBtn);
expect(getByText(/Delete this component?/)).toBeInTheDocument();
expect(getByText(/Deleting this component is permanent and cannot be undone./)).toBeInTheDocument();
expect(getByRole('button', { name: deleteModalMessages.cancelButton.defaultMessage })).toBeInTheDocument();
expect(getByRole('button', { name: deleteModalMessages.deleteButton.defaultMessage })).toBeInTheDocument();
userEvent.click(getByRole('button', { name: deleteModalMessages.cancelButton.defaultMessage }));
expect(handleDeleteMock).not.toHaveBeenCalled();
userEvent.click(getByText(messages.blockLabelButtonDelete.defaultMessage));
expect(getByText(/Delete this component?/)).toBeInTheDocument();
userEvent.click(deleteBtn);
userEvent.click(getByRole('button', { name: deleteModalMessages.deleteButton.defaultMessage }));
expect(handleDeleteMock).toHaveBeenCalled();
expect(handleDeleteMock).toHaveBeenCalledWith(xblockData.block_id);
});
});
});

View File

@@ -0,0 +1,15 @@
.course-unit {
.pgn__card .pgn__card-header {
border-bottom: 1px solid $light-400;
padding-bottom: map-get($spacers, 2);
.pgn__card-header-content {
margin-top: map-get($spacers, 3\.5);
}
.btn-icon .btn-icon__icon {
width: 1.5rem;
height: 1.5rem;
}
}
}

View File

@@ -0,0 +1,34 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
blockAltButtonEdit: {
id: 'course-authoring.course-unit.xblock.button.edit.alt',
defaultMessage: 'Edit Item',
},
blockActionsDropdownAlt: {
id: 'course-authoring.course-unit.xblock.button.actions.alt',
defaultMessage: 'Actions',
},
blockLabelButtonCopy: {
id: 'course-authoring.course-unit.xblock.button.copy.label',
defaultMessage: 'Copy',
},
blockLabelButtonDuplicate: {
id: 'course-authoring.course-unit.xblock.button.duplicate.label',
defaultMessage: 'Duplicate',
},
blockLabelButtonMove: {
id: 'course-authoring.course-unit.xblock.button.move.label',
defaultMessage: 'Move',
},
blockLabelButtonManageAccess: {
id: 'course-authoring.course-unit.xblock.button.manageAccess.label',
defaultMessage: 'Manage access',
},
blockLabelButtonDelete: {
id: 'course-authoring.course-unit.xblock.button.delete.label',
defaultMessage: 'Delete',
},
});
export default messages;

View File

@@ -19,6 +19,7 @@ export const getCourseSectionVerticalApiUrl = (itemId) => `${getStudioBaseUrl()}
export const getLearningSequencesOutlineApiUrl = (courseId) => `${getLmsBaseUrl()}/api/learning_sequences/v1/course_outline/${courseId}`;
export const getCourseMetadataApiUrl = (courseId) => `${getLmsBaseUrl()}/api/courseware/course/${courseId}`;
export const getCourseHomeCourseMetadataApiUrl = (courseId) => `${getLmsBaseUrl()}/api/course_home/course_metadata/${courseId}`;
export const getCourseVerticalChildrenApiUrl = (itemId) => `${getStudioBaseUrl()}/api/contentstore/v1/container/vertical/${itemId}/children`;
export const postXBlockBaseApiUrl = () => `${getStudioBaseUrl()}/xblock/`;
@@ -128,3 +129,43 @@ export async function createCourseXblock({
return data;
}
/**
* Get an object containing course section vertical children data.
* @param {string} itemId
* @returns {Promise<Object>}
*/
export async function getCourseVerticalChildren(itemId) {
const { data } = await getAuthenticatedHttpClient()
.get(getCourseVerticalChildrenApiUrl(itemId));
return camelCaseObject(data);
}
/**
* Delete a unit item.
* @param {string} itemId
* @returns {Promise<Object>}
*/
export async function deleteUnitItem(itemId) {
const { data } = await getAuthenticatedHttpClient()
.delete(getXBlockBaseApiUrl(itemId));
return data;
}
/**
* Duplicate a unit item.
* @param {string} itemId
* @param {string} XBlockId
* @returns {Promise<Object>}
*/
export async function duplicateUnitItem(itemId, XBlockId) {
const { data } = await getAuthenticatedHttpClient()
.post(postXBlockBaseApiUrl(), {
parent_locator: itemId,
duplicate_source_locator: XBlockId,
});
return data;
}

View File

@@ -16,6 +16,7 @@ export const getCoursewareMeta = state => state.models.coursewareMeta;
export const getSections = state => state.models.sections;
export const getCourseId = state => state.courseDetail.courseId;
export const getSequenceId = state => state.courseUnit.sequenceId;
export const getCourseVerticalChildren = state => state.courseUnit.courseVerticalChildren;
export const sequenceIdsSelector = createSelector(
[getCourseStatus, getCoursewareMeta, getSections, getCourseId],
(courseStatus, coursewareMeta, sections, courseId) => {

View File

@@ -12,9 +12,11 @@ const slice = createSlice({
loadingStatus: {
fetchUnitLoadingStatus: RequestStatus.IN_PROGRESS,
courseSectionVerticalLoadingStatus: RequestStatus.IN_PROGRESS,
courseVerticalChildrenLoadingStatus: RequestStatus.IN_PROGRESS,
},
unit: {},
courseSectionVertical: {},
courseVerticalChildren: [],
},
reducers: {
fetchCourseItemSuccess: (state, { payload }) => {
@@ -87,6 +89,28 @@ const slice = createSlice({
fetchUnitLoadingStatus: payload.status,
};
},
updateCourseVerticalChildren: (state, { payload }) => {
state.courseVerticalChildren = payload;
},
updateCourseVerticalChildrenLoadingStatus: (state, { payload }) => {
state.loadingStatus.courseVerticalChildrenLoadingStatus = payload.status;
},
deleteXBlock: (state, { payload }) => {
state.courseVerticalChildren.children = state.courseVerticalChildren.children.filter(
(component) => component.blockId !== payload,
);
},
duplicateXBlock: (state, { payload }) => {
state.courseVerticalChildren = {
...payload.newCourseVerticalChildren,
children: payload.newCourseVerticalChildren.children.map((component) => {
if (component.blockId === payload.newId) {
component.shouldScroll = true;
}
return component;
}),
};
},
},
});
@@ -107,6 +131,10 @@ export const {
changeEditTitleFormOpen,
updateQueryPendingStatus,
updateLoadingCourseXblockStatus,
updateCourseVerticalChildren,
updateCourseVerticalChildrenLoadingStatus,
deleteXBlock,
duplicateXBlock,
} = slice.actions;
export const {

View File

@@ -17,6 +17,9 @@ import {
getCourseHomeCourseMetadata,
getCourseSectionVerticalData,
createCourseXblock,
getCourseVerticalChildren,
deleteUnitItem,
duplicateUnitItem,
} from './api';
import {
updateLoadingCourseUnitStatus,
@@ -32,6 +35,10 @@ import {
fetchCourseSectionVerticalDataSuccess,
updateLoadingCourseSectionVerticalDataStatus,
updateLoadingCourseXblockStatus,
updateCourseVerticalChildren,
updateCourseVerticalChildrenLoadingStatus,
deleteXBlock,
duplicateXBlock,
} from './slice';
export function fetchCourseUnitQuery(courseId) {
@@ -192,7 +199,7 @@ export function fetchCourse(courseId) {
};
}
export function createNewCourseXblock(body, callback) {
export function createNewCourseXBlock(body, callback, blockId) {
return async (dispatch) => {
dispatch(updateLoadingCourseXblockStatus({ status: RequestStatus.IN_PROGRESS }));
dispatch(showProcessingNotification(NOTIFICATION_MESSAGES.adding));
@@ -205,7 +212,8 @@ export function createNewCourseXblock(body, callback) {
const courseSectionVerticalData = await getCourseSectionVerticalData(result.locator);
dispatch(fetchCourseSectionVerticalDataSuccess(courseSectionVerticalData));
}
// ToDo: implement fetching (update) xblocks after success creating
const courseVerticalChildrenData = await getCourseVerticalChildren(blockId);
dispatch(updateCourseVerticalChildren(courseVerticalChildrenData));
dispatch(hideProcessingNotification());
dispatch(updateLoadingCourseXblockStatus({ status: RequestStatus.SUCCESSFUL }));
dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL }));
@@ -221,3 +229,55 @@ export function createNewCourseXblock(body, callback) {
}
};
}
export function fetchCourseVerticalChildrenData(itemId) {
return async (dispatch) => {
dispatch(updateCourseVerticalChildrenLoadingStatus({ status: RequestStatus.IN_PROGRESS }));
try {
const courseVerticalChildrenData = await getCourseVerticalChildren(itemId);
dispatch(updateCourseVerticalChildren(courseVerticalChildrenData));
dispatch(updateCourseVerticalChildrenLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateCourseVerticalChildrenLoadingStatus({ status: RequestStatus.FAILED }));
}
};
}
export function deleteUnitItemQuery(itemId, xblockId) {
return async (dispatch) => {
dispatch(updateSavingStatus({ status: RequestStatus.PENDING }));
dispatch(showProcessingNotification(NOTIFICATION_MESSAGES.deleting));
try {
await deleteUnitItem(xblockId);
dispatch(deleteXBlock(xblockId));
dispatch(hideProcessingNotification());
dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(hideProcessingNotification());
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
}
};
}
export function duplicateUnitItemQuery(itemId, xblockId) {
return async (dispatch) => {
dispatch(updateSavingStatus({ status: RequestStatus.PENDING }));
dispatch(showProcessingNotification(NOTIFICATION_MESSAGES.duplicating));
try {
const { locator } = await duplicateUnitItem(itemId, xblockId);
const newCourseVerticalChildren = await getCourseVerticalChildren(itemId);
dispatch(duplicateXBlock({
newId: locator,
newCourseVerticalChildren,
}));
dispatch(hideProcessingNotification());
dispatch(updateSavingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(hideProcessingNotification());
dispatch(updateSavingStatus({ status: RequestStatus.FAILED }));
}
};
}

View File

@@ -4,14 +4,18 @@ import { useNavigate } from 'react-router-dom';
import { RequestStatus } from '../data/constants';
import {
createNewCourseXblock,
createNewCourseXBlock,
fetchCourseUnitQuery,
editCourseItemQuery,
fetchCourse,
fetchCourseSectionVerticalData,
fetchCourseVerticalChildrenData,
deleteUnitItemQuery,
duplicateUnitItemQuery,
} from './data/thunk';
import {
getCourseSectionVertical,
getCourseVerticalChildren,
getCourseUnitData,
getLoadingStatus,
getSavingStatus,
@@ -28,6 +32,7 @@ export const useCourseUnit = ({ courseId, blockId }) => {
const savingStatus = useSelector(getSavingStatus);
const loadingStatus = useSelector(getLoadingStatus);
const { draftPreviewLink, publishedPreviewLink } = useSelector(getCourseSectionVertical);
const courseVerticalChildren = useSelector(getCourseVerticalChildren);
const navigate = useNavigate();
const isTitleEditFormOpen = useSelector(state => state.courseUnit.isTitleEditFormOpen);
const isQueryPending = useSelector(state => state.courseUnit.isQueryPending);
@@ -67,9 +72,18 @@ export const useCourseUnit = ({ courseId, blockId }) => {
};
const handleCreateNewCourseXBlock = (body, callback) => (
dispatch(createNewCourseXblock(body, callback))
dispatch(createNewCourseXBlock(body, callback, blockId))
);
const unitXBlockActions = {
handleDelete: (XBlockId) => {
dispatch(deleteUnitItemQuery(blockId, XBlockId));
},
handleDuplicate: (XBlockId) => {
dispatch(duplicateUnitItemQuery(blockId, XBlockId));
},
};
useEffect(() => {
if (savingStatus === RequestStatus.SUCCESSFUL) {
dispatch(updateQueryPendingStatus(false));
@@ -81,6 +95,7 @@ export const useCourseUnit = ({ courseId, blockId }) => {
useEffect(() => {
dispatch(fetchCourseUnitQuery(blockId));
dispatch(fetchCourseSectionVerticalData(blockId, sequenceId));
dispatch(fetchCourseVerticalChildrenData(blockId));
dispatch(fetchCourse(courseId));
handleNavigate(sequenceId);
@@ -98,9 +113,11 @@ export const useCourseUnit = ({ courseId, blockId }) => {
isTitleEditFormOpen,
isInternetConnectionAlertFailed: savingStatus === RequestStatus.FAILED,
handleInternetConnectionFailed,
unitXBlockActions,
headerNavigationsActions,
handleTitleEdit,
handleTitleEditSubmit,
handleCreateNewCourseXBlock,
courseVerticalChildren,
};
};

View File

@@ -1,21 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
ActionRow,
Button,
AlertModal,
} from '@openedx/paragon';
import { useSelector } from 'react-redux';
import { useIntl } from '@edx/frontend-platform/i18n';
import { COURSE_BLOCK_NAMES } from '../constants';
import { getCurrentItem } from '../data/selectors';
import messages from './messages';
const DeleteModal = ({ isOpen, close, onDeleteSubmit }) => {
const DeleteModal = ({
category, isOpen, close, onDeleteSubmit,
}) => {
const intl = useIntl();
let { category } = useSelector(getCurrentItem);
category = COURSE_BLOCK_NAMES[category]?.name.toLowerCase();
return (
<AlertModal
@@ -47,6 +43,7 @@ const DeleteModal = ({ isOpen, close, onDeleteSubmit }) => {
DeleteModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
close: PropTypes.func.isRequired,
category: PropTypes.string.isRequired,
onDeleteSubmit: PropTypes.func.isRequired,
};

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { useSelector } from 'react-redux';
import { initializeMockApp } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
@@ -30,16 +29,13 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
}),
}));
const currentItemMock = {
displayName: 'Delete',
};
const renderComponent = (props) => render(
<AppProvider store={store}>
<IntlProvider locale="en">
<DeleteModal
isOpen
close={closeMock}
category="Section"
onDeleteSubmit={onDeleteSubmitMock}
{...props}
/>
@@ -60,7 +56,6 @@ describe('<DeleteModal />', () => {
store = initializeStore();
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
useSelector.mockReturnValue(currentItemMock);
});
it('render DeleteModal component correctly', () => {

View File

@@ -1013,5 +1013,38 @@
"course-authoring.course-unit.add.component.button.text": "Add Component:",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -36,5 +36,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}

View File

@@ -1013,5 +1013,38 @@
"course-authoring.certificates.sidebar.learnmore.button": "Learn more about certificates",
"course-authoring.course-unit.modal.button.text": "Select",
"course-authoring.course-unit.modal.container.title": "Add {componentTitle} component",
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel"
"course-authoring.course-unit.modal.container.cancel.button.text": "Cancel",
"course-authoring.course-unit.sidebar.title.draft.never-published": "Draft (never published)",
"course-authoring.course-unit.sidebar.title.visible.to-staff-only": "Visible to staff only",
"course-authoring.course-unit.sidebar.title.published.live": "Published and live",
"course-authoring.course-unit.sidebar.title.draft.unpublished": "Draft (unpublished changes)",
"course-authoring.course-unit.sidebar.title.published.not-yet-released": "Published (not yet released)",
"course-authoring.course-unit.sidebar.header.unit-location.title": "Unit location",
"course-authoring.course-unit.sidebar.body.note": "Note: Do not hide graded assignments after they have been released.",
"course-authoring.course-unit.publish.info.previously-published": "Previously published",
"course-authoring.course-unit.publish.info.draft.saved": "Draft saved on {editedOn} by {editedBy}",
"course-authoring.course-unit.publish.info.last.published": "Last published {publishedOn} by {publishedBy}",
"course-authoring.course-unit.release.info.unscheduled": "Unscheduled",
"course-authoring.course-unit.release.info.with-unit": "with {sectionName}",
"course-authoring.course-unit.visibility.is-visible-to.title": "IS VISIBLE TO",
"course-authoring.course-unit.visibility.will-be-visible-to.title": "WILL BE VISIBLE TO",
"course-authoring.course-unit.unit-location.title": "LOCATION ID",
"course-authoring.course-unit.unit-location.description": "To create a link to this unit from an HTML component in this course, enter /jump_to_id/{id} as the URL value",
"course-authoring.course-unit.visibility.checkbox.title": "Hide from learners",
"course-authoring.course-unit.visibility.staff-only.title": "Staff only",
"course-authoring.course-unit.visibility.staff-and-learners.title": "Staff and learners",
"course-authoring.course-unit.visibility.has-explicit-staff-lock.text": "with {date} {sectionName}",
"course-authoring.course-unit.action-buttons.publish.title": "Publish",
"course-authoring.course-unit.action-button.discard-changes.title": "Discard changes",
"course-authoring.course-unit.action-button.copy-unit.title": "Copy unit",
"course-authoring.course-unit.status.release.title": "RELEASE",
"course-authoring.course-unit.status.released.title": "RELEASED",
"course-authoring.course-unit.status.scheduled.title": "SCHEDULED",
"course-authoring.course-unit.xblock.button.edit.alt": "Edit Item",
"course-authoring.course-unit.xblock.button.copy.label": "Copy",
"course-authoring.course-unit.xblock.button.duplicate.label": "Duplicate",
"course-authoring.course-unit.xblock.button.move.label": "Move",
"course-authoring.course-unit.xblock.button.manageAccess.label": "Manage access",
"course-authoring.course-unit.xblock.button.delete.label": "Delete",
"course-authoring.course-unit.xblock.button.actions.alt": "Actions"
}