diff --git a/src/content-tags-drawer/ContentTagsDrawer.jsx b/src/content-tags-drawer/ContentTagsDrawer.jsx
index a20e78bc5..a629a1679 100644
--- a/src/content-tags-drawer/ContentTagsDrawer.jsx
+++ b/src/content-tags-drawer/ContentTagsDrawer.jsx
@@ -108,6 +108,36 @@ const ContentTagsDrawer = ({ id, onClose }) => {
}, []);
const taxonomies = useMemo(() => {
+ const sortTaxonomies = (taxonomiesList) => {
+ const taxonomiesWithData = taxonomiesList.filter(
+ (t) => t.contentTags.length !== 0,
+ );
+
+ // Count implicit tags per taxonomy.
+ // TODO This count is also calculated individually
+ // in ContentTagsCollapsible. It should only be calculated once.
+ const tagsCountBytaxonomy = {};
+ taxonomiesWithData.forEach((tax) => {
+ tagsCountBytaxonomy[tax.id] = new Set(
+ tax.contentTags.flatMap(item => item.lineage),
+ ).size;
+ });
+
+ // Sort taxonomies with data by implicit count
+ const sortedTaxonomiesWithData = taxonomiesWithData.sort(
+ (a, b) => tagsCountBytaxonomy[b.id] - tagsCountBytaxonomy[a.id],
+ );
+
+ // Empty taxonomies sorted by name.
+ // Since the query returns sorted by name,
+ // it is not necessary to do another sorting here.
+ const emptyTaxonomies = taxonomiesList.filter(
+ (t) => t.contentTags.length === 0,
+ );
+
+ return [...sortedTaxonomiesWithData, ...emptyTaxonomies];
+ };
+
if (taxonomyListData && contentTaxonomyTagsData) {
// Initialize list of content tags in taxonomies to populate
const taxonomiesList = taxonomyListData.results.map((taxonomy) => ({
@@ -125,7 +155,7 @@ const ContentTagsDrawer = ({ id, onClose }) => {
}
});
- return taxonomiesList;
+ return sortTaxonomies(taxonomiesList);
}
return [];
}, [taxonomyListData, contentTaxonomyTagsData]);
diff --git a/src/content-tags-drawer/ContentTagsDrawer.test.jsx b/src/content-tags-drawer/ContentTagsDrawer.test.jsx
index 91392689e..a87f5f3e4 100644
--- a/src/content-tags-drawer/ContentTagsDrawer.test.jsx
+++ b/src/content-tags-drawer/ContentTagsDrawer.test.jsx
@@ -96,16 +96,78 @@ describe('', () => {
},
],
},
+ {
+ name: 'Taxonomy 2',
+ taxonomyId: 124,
+ canTagObject: true,
+ tags: [
+ {
+ value: 'Tag 1',
+ lineage: ['Tag 1'],
+ canDeleteObjecttag: true,
+ },
+ ],
+ },
+ {
+ name: 'Taxonomy 3',
+ taxonomyId: 125,
+ canTagObject: true,
+ tags: [
+ {
+ value: 'Tag 1.1.1',
+ lineage: ['Tag 1', 'Tag 1.1', 'Tag 1.1.1'],
+ canDeleteObjecttag: true,
+ },
+ ],
+ },
+ {
+ name: '(B) Taxonomy 4',
+ taxonomyId: 126,
+ canTagObject: true,
+ tags: [],
+ },
+ {
+ name: '(A) Taxonomy 5',
+ taxonomyId: 127,
+ canTagObject: true,
+ tags: [],
+ },
],
},
});
getTaxonomyListData.mockResolvedValue({
- results: [{
- id: 123,
- name: 'Taxonomy 1',
- description: 'This is a description 1',
- canTagObject: true,
- }],
+ results: [
+ {
+ id: 123,
+ name: 'Taxonomy 1',
+ description: 'This is a description 1',
+ canTagObject: true,
+ },
+ {
+ id: 124,
+ name: 'Taxonomy 2',
+ description: 'This is a description 2',
+ canTagObject: true,
+ },
+ {
+ id: 125,
+ name: 'Taxonomy 3',
+ description: 'This is a description 3',
+ canTagObject: true,
+ },
+ {
+ id: 127,
+ name: '(A) Taxonomy 5',
+ description: 'This is a description 5',
+ canTagObject: true,
+ },
+ {
+ id: 126,
+ name: '(B) Taxonomy 4',
+ description: 'This is a description 4',
+ canTagObject: true,
+ },
+ ],
});
useTaxonomyTagsData.mockReturnValue({
@@ -388,4 +450,25 @@ describe('', () => {
postMessageSpy.mockRestore();
});
+
+ it('should taxonomies must be ordered', async () => {
+ setupMockDataForStagedTagsTesting();
+ render();
+ expect(await screen.findByText('Taxonomy 1')).toBeInTheDocument();
+
+ // First, taxonomies with content sorted by count implicit
+ // Later, empty taxonomies sorted by name
+ const expectedOrder = [
+ 'Taxonomy 3', // 3 tags
+ 'Taxonomy 1', // 2 tags
+ 'Taxonomy 2', // 1 tag
+ '(A) Taxonomy 5',
+ '(B) Taxonomy 4',
+ ];
+
+ const taxonomies = screen.getAllByText(/.*Taxonomy.*/);
+ for (let i = 0; i !== taxonomies.length; i++) {
+ expect(taxonomies[i].textContent).toBe(expectedOrder[i]);
+ }
+ });
});