diff --git a/src/taxonomy/TaxonomyListPage.jsx b/src/taxonomy/TaxonomyListPage.jsx
index 5d73ef6644..bce0a4f2da 100644
--- a/src/taxonomy/TaxonomyListPage.jsx
+++ b/src/taxonomy/TaxonomyListPage.jsx
@@ -1,18 +1,38 @@
import React from 'react';
import {
+ Button,
CardView,
Container,
DataTable,
Spinner,
} from '@edx/paragon';
-import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import {
+ Add,
+} from '@edx/paragon/icons';
+import { injectIntl, intlShape, useIntl } from '@edx/frontend-platform/i18n';
import { StudioFooter } from '@edx/frontend-component-footer';
+
import Header from '../header';
import SubHeader from '../generic/sub-header/SubHeader';
+import { actions as importActions } from './import-tags';
import messages from './messages';
import TaxonomyCard from './TaxonomyCard';
import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './api/hooks/selectors';
+const TaxonomyListHeaderButtons = () => {
+ const intl = useIntl();
+ return (
+ <>
+
+
+ >
+ );
+};
+
const TaxonomyListPage = ({ intl }) => {
const useTaxonomyListData = () => {
const taxonomyListData = useTaxonomyListDataResponse();
@@ -22,12 +42,6 @@ const TaxonomyListPage = ({ intl }) => {
const { taxonomyListData, isLoaded } = useTaxonomyListData();
- const getHeaderButtons = () => (
- // Download template and import buttons.
- // TODO Add functionality to this buttons.
- undefined
- );
-
const getOrgSelect = () => (
// Organization select component
// TODO Add functionality to this component
@@ -49,7 +63,7 @@ const TaxonomyListPage = ({ intl }) => {
}
hideBorder
/>
diff --git a/src/taxonomy/import-tags/data/actions.js b/src/taxonomy/import-tags/data/actions.js
new file mode 100644
index 0000000000..b905138ad7
--- /dev/null
+++ b/src/taxonomy/import-tags/data/actions.js
@@ -0,0 +1,85 @@
+import messages from '../messages';
+import { importNewTaxonomy } from './api';
+
+const importTaxonomy = async (intl) => {
+ /*
+ * This function is a temporary "Barebones" implementation of the import
+ * functionality with `prompt` and `alert`. It is intended to be replaced
+ * with a component that shows a `ModalDialog` in the future.
+ * See: https://github.com/openedx/modular-learning/issues/116
+ */
+ /* eslint-disable no-alert */
+ /* eslint-disable no-console */
+
+ const selectFile = async () => new Promise((resolve) => {
+ /*
+ * This function get a file from the user. It does this by creating a
+ * file input element, and then clicking it. This allows us to get a file
+ * from the user without using a form. The file input element is created
+ * and appended to the DOM, then clicked. When the user selects a file,
+ * the change event is fired, and the file is resolved.
+ * The file input element is then removed from the DOM.
+ */
+ const fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '.json,.csv';
+ fileInput.addEventListener('change', (event) => {
+ const file = event.target.files[0];
+ if (!file) {
+ resolve(null);
+ }
+ resolve(file);
+ document.body.removeChild(fileInput);
+ });
+
+ document.body.appendChild(fileInput);
+ fileInput.click();
+ });
+
+ const getTaxonomyName = () => {
+ let taxonomyName = null;
+ while (!taxonomyName) {
+ taxonomyName = prompt(intl.formatMessage(messages.promptTaxonomyName));
+
+ if (taxonomyName == null) {
+ break;
+ }
+
+ if (!taxonomyName) {
+ alert(intl.formatMessage(messages.promptTaxonomyNameRequired));
+ }
+ }
+ return taxonomyName;
+ };
+
+ const getTaxonomyDescription = () => prompt(intl.formatMessage(messages.promptTaxonomyDescription));
+
+ const file = await selectFile();
+
+ if (!file) {
+ return;
+ }
+
+ const taxonomyName = getTaxonomyName();
+ if (taxonomyName == null) {
+ return;
+ }
+
+ const taxonomyDescription = getTaxonomyDescription();
+ if (taxonomyDescription == null) {
+ return;
+ }
+
+ importNewTaxonomy(taxonomyName, taxonomyDescription, file)
+ .then(() => {
+ alert(intl.formatMessage(messages.importTaxonomySuccess));
+ })
+ .catch((error) => {
+ alert(intl.formatMessage(messages.importTaxonomyError));
+ console.error(error.response);
+ });
+};
+
+export default {
+ importTaxonomy,
+};
diff --git a/src/taxonomy/import-tags/data/api.js b/src/taxonomy/import-tags/data/api.js
new file mode 100644
index 0000000000..2ac634287a
--- /dev/null
+++ b/src/taxonomy/import-tags/data/api.js
@@ -0,0 +1,28 @@
+// @ts-check
+import { camelCaseObject, getConfig } from '@edx/frontend-platform';
+import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
+
+const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
+
+const getTaxonomyImportApiUrl = () => new URL(
+ 'api/content_tagging/v1/taxonomies/import/',
+ getApiBaseUrl(),
+).href;
+
+/**
+ * Import a new taxonomy
+ * @param {string} taxonomyName
+ * @param {string} taxonomyDescription
+ * @param {File} file
+ * @returns {Promise