Skip to content

Commit

Permalink
feat: Taxonomy export menu [FC-0036] (openedx#645)
Browse files Browse the repository at this point in the history
* feat: System-defined tooltip added
* feat: Taxonomy card menu added. Export menu item added
* feat: Modal for export taxonomy
* feat: Connect with export API
* test: Tests for API and selectors
* feat: Use windows.location.href to call the export endpoint
* test: ExportModal.test added
* style: Delete unnecessary code
* docs: README updated with taxonomy feature
* style: TaxonomyCard updated to a better code style
* style: injectIntl replaced by useIntl on taxonomy pages and components
* refactor: Move and rename taxonomy UI components to match 0002 ADR
* refactor: Move api to data to match with 0002 ADR
* test: Refactor ExportModal tests
* chore: Fix validations
* chore: Lint
* refactor: Moving hooks to apiHooks
* style: Nit on return null

---------

Co-authored-by: Rômulo Penido <[email protected]>
Co-authored-by: Christofer Chavez <[email protected]>
  • Loading branch information
3 people authored and Ian2012 committed Nov 15, 2023
1 parent 62cfe18 commit b00f9ff
Show file tree
Hide file tree
Showing 24 changed files with 671 additions and 177 deletions.
19 changes: 19 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,25 @@ Requirements
* ``contentstore.new_studio_mfe.use_new_export_page``: this feature flag will change the CMS to link to the new export page.
* ``contentstore.new_studio_mfe.use_new_import_page``: this feature flag will change the CMS to link to the new import page.

Feature: Tagging/Taxonomy Pages
================================

.. image:: ./docs/readme-images/feature-tagging-taxonomy-pages.png

Requirements
------------

* ``edx-platform`` Waffle flags:

* ``contentstore.new_studio_mfe.use_tagging_taxonomy_list_page``: this feature flag must be enabled.

Configuration
-------------

In additional to the standard settings, the following local configuration items are required:

* ``ENABLE_TAGGING_TAXONOMY_PAGES``: must be enabled in order to actually present the new Tagging/Taxonomy pages.


Developing
**********
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
@import "course-updates/CourseUpdates";
@import "export-page/CourseExportPage";
@import "import-page/CourseImportPage";
@import "taxonomy/taxonomy-card/TaxonomyCard";
@import "files-and-videos";
79 changes: 0 additions & 79 deletions src/taxonomy/TaxonomyCard.jsx

This file was deleted.

15 changes: 7 additions & 8 deletions src/taxonomy/TaxonomyListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import {
DataTable,
Spinner,
} from '@edx/paragon';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
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 messages from './messages';
import TaxonomyCard from './TaxonomyCard';
import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './api/hooks/selectors';
import TaxonomyCard from './taxonomy-card';
import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './data/apiHooks';

const TaxonomyListPage = ({ intl }) => {
const TaxonomyListPage = () => {
const intl = useIntl();
const useTaxonomyListData = () => {
const taxonomyListData = useTaxonomyListDataResponse();
const isLoaded = useIsTaxonomyListDataLoaded();
Expand Down Expand Up @@ -97,8 +98,6 @@ const TaxonomyListPage = ({ intl }) => {
);
};

TaxonomyListPage.propTypes = {
intl: intlShape.isRequired,
};
TaxonomyListPage.propTypes = {};

export default injectIntl(TaxonomyListPage);
export default TaxonomyListPage;
4 changes: 2 additions & 2 deletions src/taxonomy/TaxonomyListPage.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { act, render } from '@testing-library/react';
import initializeStore from '../store';

import TaxonomyListPage from './TaxonomyListPage';
import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './api/hooks/selectors';
import { useTaxonomyListDataResponse, useIsTaxonomyListDataLoaded } from './data/apiHooks';

let store;

jest.mock('./api/hooks/selectors', () => ({
jest.mock('./data/apiHooks', () => ({
useTaxonomyListDataResponse: jest.fn(),
useIsTaxonomyListDataLoaded: jest.fn(),
}));
Expand Down
2 changes: 2 additions & 0 deletions src/taxonomy/__mocks__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as taxonomyListMock } from './taxonomyListMock';
50 changes: 50 additions & 0 deletions src/taxonomy/__mocks__/taxonomyListMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module.exports = {
next: null,
previous: null,
count: 4,
numPages: 1,
currentPage: 1,
start: 0,
results: [
{
id: -2,
name: 'Content Authors',
description: 'Allows tags for any user ID created on the instance.',
enabled: true,
allowMultiple: false,
allowFreeText: false,
systemDefined: true,
visibleToAuthors: false,
},
{
id: -1,
name: 'Languages',
description: 'lang lang lang lang lang lang lang lang',
enabled: true,
allowMultiple: false,
allowFreeText: false,
systemDefined: true,
visibleToAuthors: true,
},
{
id: 1,
name: 'Taxonomy',
description: 'This is a Description',
enabled: true,
allowMultiple: false,
allowFreeText: false,
systemDefined: false,
visibleToAuthors: true,
},
{
id: 2,
name: 'Taxonomy long long long long long long long long long long long long long long long long long long long',
description: 'This is a Description long lon',
enabled: true,
allowMultiple: false,
allowFreeText: false,
systemDefined: false,
visibleToAuthors: true,
},
],
};
20 changes: 0 additions & 20 deletions src/taxonomy/api/hooks/api.js

This file was deleted.

25 changes: 0 additions & 25 deletions src/taxonomy/api/hooks/api.test.js

This file was deleted.

20 changes: 0 additions & 20 deletions src/taxonomy/api/hooks/selectors.js

This file was deleted.

29 changes: 29 additions & 0 deletions src/taxonomy/data/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @ts-check
import { camelCaseObject, getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
export const getTaxonomyListApiUrl = () => new URL('api/content_tagging/v1/taxonomies/?enabled=true', getApiBaseUrl()).href;
export const getExportTaxonomyApiUrl = (pk, format) => new URL(
`api/content_tagging/v1/taxonomies/${pk}/export/?output_format=${format}&download=1`,
getApiBaseUrl(),
).href;

/**
* Get list of taxonomies.
* @returns {Promise<Object>}
*/
export async function getTaxonomyListData() {
const { data } = await getAuthenticatedHttpClient().get(getTaxonomyListApiUrl());
return camelCaseObject(data);
}

/**
* Downloads the file of the exported taxonomy
* @param {number} pk
* @param {string} format
* @returns {void}
*/
export function getTaxonomyExportFile(pk, format) {
window.location.href = getExportTaxonomyApiUrl(pk, format);
}
61 changes: 61 additions & 0 deletions src/taxonomy/data/api.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import MockAdapter from 'axios-mock-adapter';
import { initializeMockApp } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

import { taxonomyListMock } from '../__mocks__';

import {
getTaxonomyListApiUrl,
getExportTaxonomyApiUrl,
getTaxonomyListData,
getTaxonomyExportFile,
} from './api';

let axiosMock;

describe('taxonomy api calls', () => {
const { location } = window;
beforeEach(() => {
initializeMockApp({
authenticatedUser: {
userId: 3,
username: 'abc123',
administrator: true,
roles: [],
},
});
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});

afterEach(() => {
jest.clearAllMocks();
});

beforeAll(() => {
delete window.location;
window.location = {
href: '',
};
});

afterAll(() => {
window.location = location;
});

it('should get taxonomy list data', async () => {
axiosMock.onGet(getTaxonomyListApiUrl()).reply(200, taxonomyListMock);
const result = await getTaxonomyListData();

expect(axiosMock.history.get[0].url).toEqual(getTaxonomyListApiUrl());
expect(result).toEqual(taxonomyListMock);
});

it('should set window.location.href correctly', () => {
const pk = 1;
const format = 'json';

getTaxonomyExportFile(pk, format);

expect(window.location.href).toEqual(getExportTaxonomyApiUrl(pk, format));
});
});
Loading

0 comments on commit b00f9ff

Please sign in to comment.