+
+
+ );
+};
diff --git a/src/library-authoring/import-course/index.scss b/src/library-authoring/import-course/index.scss
new file mode 100644
index 000000000..74012aea1
--- /dev/null
+++ b/src/library-authoring/import-course/index.scss
@@ -0,0 +1,19 @@
+.status-border-imported {
+ border-left: 8px solid #5690BB;
+}
+
+.status-border-failed {
+ border-left: 8px solid var(--pgn-color-danger-500);
+}
+
+.status-border-partial {
+ border-left: 8px solid var(--pgn-color-warning-500);
+}
+
+.status-border-in-progress {
+ border-left: 8px solid #F4B57B;
+}
+
+.text-decoration-underline {
+ text-decoration: underline;
+}
diff --git a/src/library-authoring/import-course/index.ts b/src/library-authoring/import-course/index.ts
new file mode 100644
index 000000000..23de1b775
--- /dev/null
+++ b/src/library-authoring/import-course/index.ts
@@ -0,0 +1 @@
+export { CourseImportHomePage } from './CourseImportHomePage';
diff --git a/src/library-authoring/import-course/messages.ts b/src/library-authoring/import-course/messages.ts
new file mode 100644
index 000000000..e6a85b951
--- /dev/null
+++ b/src/library-authoring/import-course/messages.ts
@@ -0,0 +1,78 @@
+import { defineMessages } from '@edx/frontend-platform/i18n';
+
+const messages = defineMessages({
+ pageTitle: {
+ id: 'course-authoring.library-authoring.import-course.title',
+ defaultMessage: 'Import',
+ description: 'Title for the library import course',
+ },
+ pageSubtitle: {
+ id: 'course-authoring.library-authoring.import-course.subtitle',
+ defaultMessage: 'Tools',
+ description: 'Subtitle for the library import course',
+ },
+ emptyStateText: {
+ id: 'course-authoring.library-authoring.import-course.empty-state.text',
+ defaultMessage: 'You have not imported any courses into this library.',
+ description: 'Text for the empty state of the library import course',
+ },
+ emptyStateButtonText: {
+ id: 'course-authoring.library-authoring.import-course.empty-state.button.text',
+ defaultMessage: 'Import Course',
+ description: 'Text for the button to import a course into the library',
+ },
+ courseImportPreviousImports: {
+ id: 'course-authoring.library-authoring.import-course.previous-imports',
+ defaultMessage: 'Previous Imports',
+ description: 'Title for the list of previous imports',
+ },
+ courseImportTextProgress: {
+ id: 'course-authoring.library-authoring.import-course.course.text',
+ defaultMessage: '% Imported',
+ description: 'Text for the course import state',
+ },
+ courseImportTextFailed: {
+ id: 'course-authoring.library-authoring.import-course.course.text-failed',
+ defaultMessage: 'Import Failed',
+ description: 'Text for the course import failed state',
+ },
+ courseImportNavigateAlt: {
+ id: 'course-authoring.library-authoring.import-course.course.navigate-alt',
+ defaultMessage: 'Navigate to course',
+ description: 'Alt text for the course import navigate button',
+ },
+ helpAndSupportTitle: {
+ id: 'course-authoring.library-authoring.import-course.help-and-support.title',
+ defaultMessage: 'Help & Support',
+ description: 'Title of the Help & Support sidebar',
+ },
+ helpAndSupportFirstQuestionTitle: {
+ id: 'course-authoring.library-authoring.import-course.help-and-support.q1.title',
+ defaultMessage: 'Why import a course?',
+ description: 'Title of the first question in the Help & Support sidebar',
+ },
+ helpAndSupportFirstQuestionBody: {
+ id: 'course-authoring.library-authoring.import-course.help-and-support.q1.body',
+ defaultMessage: '
You can import existing courses into a library in order to reference '
+ + 'course content across courses.
'
+ + '
Courses with content you or others may want to reuse or reference in the future are '
+ + 'excellent candidates for import.
',
+ description: 'Body of the first question in the Help & Support sidebar',
+ },
+ helpAndSupportSecondQuestionTitle: {
+ id: 'course-authoring.library-authoring.import-course.help-and-support.q2.title',
+ defaultMessage: 'What content is imported?',
+ description: 'Title of the second question in the Help & Support sidebar',
+ },
+ helpAndSupportSecondQuestionBody: {
+ id: 'course-authoring.library-authoring.import-course.help-and-support.q2.body',
+ defaultMessage: '
You can select a course to import and decide whether to import all sections, '
+ + 'subsections, units, or blocks from this course.
'
+ + '
Not all courses content types can be imported, but this page will convey the status of imports '
+ + 'and share any import errors found while importing your course.
'
+ + '
For additional details you can review the Library Import documentation.
',
+ description: 'Body of the second question in the Help & Support sidebar',
+ },
+});
+
+export default messages;
diff --git a/src/library-authoring/index.scss b/src/library-authoring/index.scss
index 1404cb68f..43390d63d 100644
--- a/src/library-authoring/index.scss
+++ b/src/library-authoring/index.scss
@@ -6,6 +6,7 @@
@import "./section-subsections";
@import "./containers";
@import "./hierarchy";
+@import "./import-course";
.library-cards-grid {
display: grid;
diff --git a/src/library-authoring/library-info/LibraryInfoHeader.test.tsx b/src/library-authoring/library-info/LibraryInfoHeader.test.tsx
index 33630af5b..f93975643 100644
--- a/src/library-authoring/library-info/LibraryInfoHeader.test.tsx
+++ b/src/library-authoring/library-info/LibraryInfoHeader.test.tsx
@@ -6,7 +6,8 @@ import {
screen,
waitFor,
initializeMocks,
-} from '../../testUtils';
+} from '@src/testUtils';
+
import { mockContentLibrary } from '../data/api.mocks';
import { getContentLibraryApiUrl } from '../data/api';
import { LibraryProvider } from '../common/context/LibraryContext';
diff --git a/src/library-authoring/library-info/LibraryInfoHeader.tsx b/src/library-authoring/library-info/LibraryInfoHeader.tsx
index cafeccf26..00d5b304a 100644
--- a/src/library-authoring/library-info/LibraryInfoHeader.tsx
+++ b/src/library-authoring/library-info/LibraryInfoHeader.tsx
@@ -8,7 +8,7 @@ import {
import { Edit } from '@openedx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';
-import { ToastContext } from '../../generic/toast-context';
+import { ToastContext } from '@src/generic/toast-context';
import { useLibraryContext } from '../common/context/LibraryContext';
import { useUpdateLibraryMetadata } from '../data/apiHooks';
import messages from './messages';
diff --git a/src/library-authoring/routes.ts b/src/library-authoring/routes.ts
index 124264016..e052c6fc4 100644
--- a/src/library-authoring/routes.ts
+++ b/src/library-authoring/routes.ts
@@ -47,6 +47,8 @@ export const ROUTES = {
UNIT: '/unit/:containerId/:selectedItemId?/:index?',
// LibraryBackupPage route:
BACKUP: '/backup',
+ // LibraryImportPage route:
+ IMPORT: '/import',
};
export enum ContentType {
diff --git a/src/utils.tsx b/src/utils.tsx
index 1432a2ce1..f57d434a0 100644
--- a/src/utils.tsx
+++ b/src/utils.tsx
@@ -349,3 +349,5 @@ export const skipIfUnwantedTarget = (
};
export const BoldText = (chunk: string[]) => {chunk};
+export const Div = (chunk: string[]) =>