diff --git a/src/content-tags-drawer/data/api.js b/src/content-tags-drawer/data/api.js index b5b28514f9..8f61f911e1 100644 --- a/src/content-tags-drawer/data/api.js +++ b/src/content-tags-drawer/data/api.js @@ -36,7 +36,7 @@ export const getLibraryContentDataApiUrl = (contentId) => new URL(`/api/librarie * Get all tags that belong to taxonomy. * @param {number} taxonomyId The id of the taxonomy to fetch tags for * @param {{page?: number, searchTerm?: string, parentTag?: string}} options - * @returns {Promise} + * @returns {Promise} */ export async function getTaxonomyTagsData(taxonomyId, options = {}) { const url = getTaxonomyTagsApiUrl(taxonomyId, options); diff --git a/src/content-tags-drawer/data/apiHooks.jsx b/src/content-tags-drawer/data/apiHooks.jsx index 44151727a5..869cb8280d 100644 --- a/src/content-tags-drawer/data/apiHooks.jsx +++ b/src/content-tags-drawer/data/apiHooks.jsx @@ -27,7 +27,7 @@ import { * tagPages: { * isLoading: boolean, * isError: boolean, - * data: TagListData[], + * data: TagData[], * }[], * }} */ @@ -53,14 +53,14 @@ export const useTaxonomyTagsData = (taxonomyId, parentTag = null, numPages = 1, const hasMorePages = numPages < totalPages; const tagPages = useMemo(() => { - /** @type { { isLoading: boolean, isError: boolean, data: TagListData[] }[] } */ + /** @type { { isLoading: boolean, isError: boolean, data: TagData[] }[] } */ const newTags = []; // Pre-load desendants if possible const preLoadedData = new Map(); dataPages.forEach(result => { - /** @type {TagListData[]} */ + /** @type {TagData[]} */ const simplifiedTagsList = []; result.data?.results?.forEach((tag) => { @@ -79,7 +79,7 @@ export const useTaxonomyTagsData = (taxonomyId, parentTag = null, numPages = 1, // Store the pre-loaded descendants into the query cache: preLoadedData.forEach((tags, parentValue) => { const queryKey = ['taxonomyTags', taxonomyId, parentValue, 1, searchTerm]; - /** @type {TagData} */ + /** @type {TagListData} */ const cachedData = { next: '', previous: '', diff --git a/src/taxonomy/TaxonomyListPage.jsx b/src/taxonomy/TaxonomyListPage.jsx index 4e77b12641..290c3bdc06 100644 --- a/src/taxonomy/TaxonomyListPage.jsx +++ b/src/taxonomy/TaxonomyListPage.jsx @@ -1,3 +1,4 @@ +// @ts-check import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { @@ -39,13 +40,14 @@ const TaxonomyListHeaderButtons = () => { + {intl.formatMessage(messages.downloadTemplateButtonHint)} )} > - + @@ -185,7 +187,7 @@ const TaxonomyListPage = () => {
- {isLoaded && ( + {isLoaded && taxonomyListData && ( { accessor: 'systemDefined', }, { + Header: '', accessor: 'tagsCount', }, ]} @@ -235,11 +238,15 @@ const TaxonomyListPage = () => { OrganizationFilterSelector.propTypes = { isOrganizationListLoaded: PropTypes.bool.isRequired, - organizationListData: PropTypes.arrayOf(PropTypes.string).isRequired, + organizationListData: PropTypes.arrayOf(PropTypes.string), selectedOrgFilter: PropTypes.string.isRequired, setSelectedOrgFilter: PropTypes.func.isRequired, }; +OrganizationFilterSelector.defaultProps = { + organizationListData: null, +}; + TaxonomyListPage.propTypes = {}; export default TaxonomyListPage; diff --git a/src/taxonomy/delete-dialog/index.jsx b/src/taxonomy/delete-dialog/index.jsx index 6b5999fada..d06faecb00 100644 --- a/src/taxonomy/delete-dialog/index.jsx +++ b/src/taxonomy/delete-dialog/index.jsx @@ -1,4 +1,5 @@ -import React, { useState } from 'react'; +// @ts-check +import React, { useCallback, useState } from 'react'; import { ActionRow, Button, @@ -23,13 +24,13 @@ const DeleteDialog = ({ const [deleteButtonDisabled, setDeleteButtonDisabled] = useState(true); const deleteLabel = intl.formatMessage(messages.deleteDialogConfirmDeleteLabel); - const handleInputChange = React.useCallback((event) => { + const handleInputChange = useCallback((event) => { if (event.target.value === deleteLabel) { setDeleteButtonDisabled(false); } else { setDeleteButtonDisabled(true); } - }); + }, []); const onClickDelete = React.useCallback(() => { onClose(); @@ -55,10 +56,7 @@ const DeleteDialog = ({
- {/* Delete `(?)` after implement get tags count of a taxonomy */} - {intl.formatMessage(messages.deleteDialogBody, { - tagsCount: tagsCount !== undefined ? tagsCount : '(?)', - })} + {intl.formatMessage(messages.deleteDialogBody, { tagsCount })}
diff --git a/src/taxonomy/tag-list/TagListTable.jsx b/src/taxonomy/tag-list/TagListTable.jsx index 1e2638fae3..c762db9c12 100644 --- a/src/taxonomy/tag-list/TagListTable.jsx +++ b/src/taxonomy/tag-list/TagListTable.jsx @@ -1,9 +1,9 @@ -// ts-check +// @ts-check +import React, { useState } from 'react'; import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { DataTable } from '@edx/paragon'; -import _ from 'lodash'; +import { isEqual } from 'lodash'; import Proptypes from 'prop-types'; -import { useState } from 'react'; import { LoadingSpinner } from '../../generic/Loading'; import messages from './messages'; @@ -51,7 +51,14 @@ const TagValue = ({ row }) => ( {` (${row.original.childCount})`} ); -TagValue.propTypes = DataTable.TableCell.propTypes; +TagValue.propTypes = { + row: Proptypes.shape({ + original: Proptypes.shape({ + value: Proptypes.string.isRequired, + childCount: Proptypes.number.isRequired, + }).isRequired, + }).isRequired, +}; const TagListTable = ({ taxonomyId }) => { const intl = useIntl(); @@ -62,7 +69,7 @@ const TagListTable = ({ taxonomyId }) => { const tagList = useTagListDataResponse(taxonomyId, options); const fetchData = (args) => { - if (!_.isEqual(args, options)) { + if (!isEqual(args, options)) { setOptions({ ...args }); } }; diff --git a/src/taxonomy/tag-list/data/api.js b/src/taxonomy/tag-list/data/api.js index a039223eed..4fcb5e89f7 100644 --- a/src/taxonomy/tag-list/data/api.js +++ b/src/taxonomy/tag-list/data/api.js @@ -18,7 +18,7 @@ const getTagListApiUrl = (taxonomyId, page) => new URL( * @param {number} taxonomyId * @param {import('./types.mjs').QueryOptions} options * @returns {import('@tanstack/react-query').UseQueryResult} - */ // eslint-disable-next-line import/prefer-default-export + */ export const useTagListData = (taxonomyId, options) => { const { pageIndex } = options; return useQuery({ @@ -36,7 +36,7 @@ export const useTagListData = (taxonomyId, options) => { * something more sophisticated later, as we improve the "taxonomy details" page. * @param {number} taxonomyId * @param {string} parentTagValue - * @returns {import('@tanstack/react-query').UseQueryResult} + * @returns {import('@tanstack/react-query').UseQueryResult} */ export const useSubTags = (taxonomyId, parentTagValue) => useQuery({ queryKey: ['subtagsList', taxonomyId, parentTagValue], diff --git a/src/taxonomy/tag-list/data/types.mjs b/src/taxonomy/tag-list/data/types.mjs index bd22d27a5b..694f65b343 100644 --- a/src/taxonomy/tag-list/data/types.mjs +++ b/src/taxonomy/tag-list/data/types.mjs @@ -9,9 +9,8 @@ * @property {number} pageIndex */ -// FIXME: this should be renamed to TagData /** - * @typedef {Object} TagListData + * @typedef {Object} TagData * @property {number} childCount * @property {number} depth * @property {string} externalId @@ -23,14 +22,13 @@ * @property {string?} _id Database ID. Don't rely on this, as it is not present for free-text tags. */ -// FIXME: this should be renamed to TagListData /** - * @typedef {Object} TagData + * @typedef {Object} TagListData * @property {number} count * @property {number} currentPage * @property {string} next * @property {number} numPages * @property {string} previous - * @property {TagListData[]} results + * @property {TagData[]} results * @property {number} start */ diff --git a/src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx b/src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx index c1d15da5a3..74fbee85f7 100644 --- a/src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx +++ b/src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx @@ -121,12 +121,19 @@ const TaxonomyMenu = ({ ); + const toggleProps = iconMenu ? { + as: IconButton, + src: MoreVert, + iconAs: Icon, + } : { + as: Button, + }; + return ( - ev.preventDefault()}> + ev.preventDefault()}> cannot appear as a descendant of warning onClick={ (e) => { e.preventDefault();