From f8cfcb8ef5b786c6e21620342ae735621072a4cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Wed, 1 Nov 2023 17:49:15 -0300 Subject: [PATCH 1/2] feat: add download taxonomy template button --- src/taxonomy/TaxonomyListPage.jsx | 48 ++++++++++++++++++++++++----- src/taxonomy/data/api.js | 13 ++++++++ src/taxonomy/data/thunks.js | 13 ++++++-- src/taxonomy/export-modal/index.jsx | 2 +- src/taxonomy/messages.js | 12 ++++++++ 5 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/taxonomy/TaxonomyListPage.jsx b/src/taxonomy/TaxonomyListPage.jsx index c9751b2f6e..5eebfd9f00 100644 --- a/src/taxonomy/TaxonomyListPage.jsx +++ b/src/taxonomy/TaxonomyListPage.jsx @@ -1,18 +1,58 @@ import React from 'react'; import { + Button, CardView, Container, DataTable, + Dropdown, + DropdownButton, + OverlayTrigger, Spinner, + Tooltip, } from '@edx/paragon'; +import { + Add, +} from '@edx/paragon/icons'; import { StudioFooter } from '@edx/frontend-component-footer'; import { useIntl } from '@edx/frontend-platform/i18n'; import Header from '../header'; import SubHeader from '../generic/sub-header/SubHeader'; +import { downloadTaxonomyTemplate } from './data/thunks'; import messages from './messages'; import TaxonomyCard from './taxonomy-card'; import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './hooks'; +const TaxonomyListHeaderButtons = () => { + const intl = useIntl(); + return ( + <> + + {intl.formatMessage(messages.downloadTemplateButtonHint)} + + )} + > + + downloadTaxonomyTemplate('csv')}> + {intl.formatMessage(messages.downloadTemplateButtonCSVLabel)} + + downloadTaxonomyTemplate('json')}> + {intl.formatMessage(messages.downloadTemplateButtonJSONLabel)} + + + + + + ); +}; + const TaxonomyListPage = () => { const intl = useIntl(); const useTaxonomyListData = () => { @@ -23,12 +63,6 @@ const TaxonomyListPage = () => { 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 @@ -50,7 +84,7 @@ const TaxonomyListPage = () => { } hideBorder /> diff --git a/src/taxonomy/data/api.js b/src/taxonomy/data/api.js index 513f7fdaf9..e9236dd929 100644 --- a/src/taxonomy/data/api.js +++ b/src/taxonomy/data/api.js @@ -8,6 +8,10 @@ export const getExportTaxonomyApiUrl = (pk, format) => new URL( `api/content_tagging/v1/taxonomies/${pk}/export/?output_format=${format}&download=1`, getApiBaseUrl(), ).href; +const getTaxonomyTemplateApiUrl = (format) => new URL( + `api/content_tagging/v1/taxonomies/import/template.${format}`, + getApiBaseUrl(), +).href; /** * Get list of taxonomies. @@ -27,3 +31,12 @@ export async function getTaxonomyListData() { export function getTaxonomyExportFile(pk, format) { window.location.href = getExportTaxonomyApiUrl(pk, format); } + +/** + * Downloads the template file for import taxonomies + * @param {('json'|'csv')} format + * @returns {void} + */ +export function getTaxonomyTemplateFile(format) { + window.location.href = getTaxonomyTemplateApiUrl(format); +} diff --git a/src/taxonomy/data/thunks.js b/src/taxonomy/data/thunks.js index 44afd37722..f9ccdab4fb 100644 --- a/src/taxonomy/data/thunks.js +++ b/src/taxonomy/data/thunks.js @@ -1,5 +1,5 @@ // @ts-check -import { getTaxonomyExportFile } from './api'; +import { getTaxonomyExportFile, getTaxonomyTemplateFile } from './api'; /** * Downloads the file of the exported taxonomy @@ -7,8 +7,15 @@ import { getTaxonomyExportFile } from './api'; * @param {string} format * @returns {void} */ -const exportTaxonomy = (pk, format) => ( +export const exportTaxonomy = (pk, format) => ( getTaxonomyExportFile(pk, format) ); -export default exportTaxonomy; +/** + * Downloads the template file for import taxonomies + * @param {('json'|'csv')} format + * @returns {void} + */ +export const downloadTaxonomyTemplate = (format) => ( + getTaxonomyTemplateFile(format) +); diff --git a/src/taxonomy/export-modal/index.jsx b/src/taxonomy/export-modal/index.jsx index 7fea965225..a4e871fb20 100644 --- a/src/taxonomy/export-modal/index.jsx +++ b/src/taxonomy/export-modal/index.jsx @@ -8,7 +8,7 @@ import { import PropTypes from 'prop-types'; import { useIntl } from '@edx/frontend-platform/i18n'; import messages from './messages'; -import exportTaxonomy from '../data/thunks'; +import { exportTaxonomy } from '../data/thunks'; const ExportModal = ({ taxonomyId, diff --git a/src/taxonomy/messages.js b/src/taxonomy/messages.js index 82467e09ba..0f016db033 100644 --- a/src/taxonomy/messages.js +++ b/src/taxonomy/messages.js @@ -9,6 +9,18 @@ const messages = defineMessages({ id: 'course-authoring.taxonomy-list.button.download-template.label', defaultMessage: 'Download template', }, + downloadTemplateButtonCSVLabel: { + id: 'course-authoring.taxonomy-list.button.download-template.csv.label', + defaultMessage: 'CSV template', + }, + downloadTemplateButtonJSONLabel: { + id: 'course-authoring.taxonomy-list.button.download-template.json.label', + defaultMessage: 'JSON template', + }, + downloadTemplateButtonHint: { + id: 'course-authoring.taxonomy-list.butotn.download-template.hint', + defaultMessage: 'Download example taxonomy', + }, importButtonLabel: { id: 'course-authoring.taxonomy-list.button.import.label', defaultMessage: 'Import', From 09b9598e16a3e951230677054fee8a31ef591d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Wed, 1 Nov 2023 19:05:51 -0300 Subject: [PATCH 2/2] test: fix test error --- src/taxonomy/export-modal/ExportModal.test.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/taxonomy/export-modal/ExportModal.test.jsx b/src/taxonomy/export-modal/ExportModal.test.jsx index c9f4908911..e6c0594b63 100644 --- a/src/taxonomy/export-modal/ExportModal.test.jsx +++ b/src/taxonomy/export-modal/ExportModal.test.jsx @@ -5,7 +5,7 @@ import { AppProvider } from '@edx/frontend-platform/react'; import { render, fireEvent } from '@testing-library/react'; import ExportModal from '.'; import initializeStore from '../../store'; -import exportTaxonomy from '../data/thunks'; +import { exportTaxonomy } from '../data/thunks'; const onClose = jest.fn(); let store;