You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Blocked by:#616, "[FE] Add taxonomy type badge to Taxonomies page" (open, unmerged). #616 owns the TaxonomyData field this ticket's conditional-visibility logic keys off — that field does not exist in frontend-app-authoring today. #616 is itself blocked on backend issues #618 and #630 (unmerged). This ticket is ready for development but cannot be implemented, demoed, or tested until #616 lands.
Repo: frontend-app-authoring (Studio MFE). No backend or openedx-core change.
Use Case
As a Studio Admin or Staff user managing a Competency-type taxonomy, I want an "Apply Competencies" action available directly from the Taxonomies page — as an item in the taxonomy card's actions menu, and as a standalone card-footer button — so that I can navigate straight to that taxonomy's Competency Management page in one click, without confusing this action with the taxonomy tag-editing flow that the unchanged card click already opens.
Description
Current state
Log in to Studio as an Admin or Staff user and navigate to the Taxonomies page.
Each imported taxonomy card shows a three-dot (⋮) actions button.
Clicking the three-dot button opens a dropdown with four items, in this order: Re-import, Export, Delete, Manage Organizations.
Clicking the card body anywhere outside the three-dot button navigates to the Taxonomy Editing page (tag browsing/editing) — identical behavior for every taxonomy type.
There is no entry point from a taxonomy card into competency management. Neither the menu nor the card click leads to competency criteria authoring today. No Competency Management page exists anywhere in the MFE.
Exactly one new item, "Apply Competencies," is appended to the three-dot menu (final order: Re-import, Export, Delete, Manage Organizations, Apply Competencies), rendered only when the taxonomy's type is Competency. Tag-type taxonomies keep exactly the original four items. The label was deliberately chosen over "Manage Competencies" during [UXD] Create UX designs for taxonomy actions menu with Apply Competencies and Edit Taxonomy options #622's design discussion, to distinguish this action from the tag-editing the existing Taxonomy Editor already does.
For Competency-type taxonomies only, the card footer additionally gains a standalone "Apply Competencies" button. Both surfaces navigate to the same destination for the same taxonomy — no additional taxonomy-selection step.
A new route, /taxonomy/:taxonomyId/competencies, and a content-empty placeholder page (breadcrumb + title only) are added as the shared destination, so both entry points land somewhere real and testable.
Gating reuses the existing canChangeTaxonomy permission already used for "Manage Organizations" — no new permission tier.
Defensive handling for a Tag-type taxonomy's id typed directly into /taxonomy/:taxonomyId/competencies. No operator-facing path produces this URL for a Tag taxonomy; revisit if it becomes a real issue once the destination page has real content.
Acceptance Criteria
Scenario: Competency-type taxonomy card shows the new menu item
Given I am logged in to Studio as an Admin or Staff user
And a taxonomy of type Competency exists on the Taxonomies page
When I open the taxonomy card's three-dot actions menu
Then I see five items in order: Re-import, Export, Delete, Manage Organizations, Apply Competencies
Scenario: Tag-type taxonomy card menu is unaffected
Given a taxonomy of type Tag exists on the Taxonomies page
When I open that taxonomy card's three-dot actions menu
Then I see exactly the original four items
And "Apply Competencies" does not appear
Scenario: Card click still opens the Taxonomy Editing page, regardless of type
Given a taxonomy card of either type exists on the Taxonomies page
When I click the card body outside the three-dot button
Then I am taken to the Taxonomy Editing page for that taxonomy, unchanged from before this ticket
Scenario: Competency-type card shows a footer "Apply Competencies" button
Given a taxonomy of type Competency exists
Then its card footer displays an "Apply Competencies" button
And a Tag-type taxonomy's card footer displays no such button
Scenario: Menu item navigates to the Competency Management page
Given a taxonomy of type Competency exists
When I select "Apply Competencies" from its three-dot menu
Then I am navigated to /taxonomy/:taxonomyId/competencies for that specific taxonomy, with no extra taxonomy-selection step
And the page renders a breadcrumb and title; page content beyond that is out of scope for this ticket
Scenario: Footer button reaches the same destination as the menu item
Given a taxonomy of type Competency exists
When I click the card-footer "Apply Competencies" button
Then I land on the same route and taxonomy scope that the menu item would produce
Scenario: User without the required permission
Given I am logged in as a user without `canChangeTaxonomy` permission on a Competency-type taxonomy
When I view that taxonomy's card
Then "Apply Competencies" does not appear in the menu or as a footer button, consistent with how "Manage Organizations" is already gated
Scenario: Small-screen rendering
Given I view the Taxonomies page on a small screen
When a Competency-type card renders
Then the footer button and five-item menu remain usable, consistent with the existing Paragon Card.Footer pattern used elsewhere in this repo (e.g. GalleryCard)
Design source: openedx-core issue [UXD] Create UX designs for taxonomy actions menu with Apply Competencies and Edit Taxonomy options #622, "[UXD] Create UX designs for taxonomy actions menu with Apply Competencies and Edit Taxonomy options" — in Final Axim Review. Read it for the label rationale ("Apply Competencies" over "Manage Competencies") and the click-pattern decision (card click unchanged for all types).
**Frontend conventions:**new strings need defineMessages i18n entries following the course-authoring.taxonomy-menu.<action>.label convention already used in src/taxonomy/taxonomy-menu/messages.ts.
Code, confirmed against frontend-app-authoring HEAD:
src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx — the existing 4-item menu. Items are a {title, action, show} map (pickBy-filtered), rendered as Dropdown.Items. useNavigate is already imported (line 14) but unused; every existing action currently opens a modal via useToggle. "Apply Competencies" is the first item whose action navigates.
src/taxonomy/taxonomy-menu/messages.ts — i18n id convention: course-authoring.taxonomy-menu.<action>.label.
src/taxonomy/taxonomy-card/index.jsx — the card: Card.Header carries TaxonomyMenu as actions; Card.Body holds the description. No Card.Footer today.
src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx — the pattern to mirror for the new placeholder page: useParams → useTaxonomyDetails(taxonomyId) → Loading/ConnectionErrorAlert guards → Breadcrumb + Container.
src/taxonomy/TaxonomyLayout.tsx — chrome host (Header, StudioFooterSlot, Toast, TaxonomyContext) via <Outlet/>; any sibling route added under it inherits this chrome for free.
src/files-and-videos/generic/table-components/GalleryCard.jsx:80-85 — existing in-repo precedent for Paragon Card.Footer, confirming it's already a supported, used pattern, just not yet in taxonomy-card.
src/index.jsx:104-116 — current taxonomy routes, gated by getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'.
Technical Notes
Files to Create
File
Purpose
src/taxonomy/competency-management/index.ts
Public interface exporting CompetencyManagementPage, per this feature's module-boundary convention
Placeholder page: breadcrumb (Taxonomies → taxonomy name → Manage & Apply Competencies), fetches the taxonomy via useTaxonomyDetails, empty-state body only — no TreeView/switcher
Add a 5th menuItems entry, applyCompetencies, after manageOrgs; action calls the already-imported navigate(\/taxonomy/${taxonomy.id}/competencies`); showkeyed off the taxonomy-type field #616 adds (real field name pending — see Open Questions). Extend thetaxonomyPropTypes/JSDocPick<TaxonomyData, …>` to include it.
Add Competency-type and Tag-type fixtures; assert conditional render and that clicking navigates
src/taxonomy/taxonomy-card/index.jsx
Destructure the new type field from original; add <Card.Footer> (after Card.Body) rendered only for Competency-type, containing a Button as={NavLink} to the same route as the menu item
src/taxonomy/taxonomy-card/messages.ts
Add applyCompetenciesButton message
src/taxonomy/taxonomy-card/TaxonomyCard.test.jsx
Add Competency/Tag fixtures; assert footer button visibility and link target
src/index.jsx
Inside the existing ENABLE_TAGGING_TAXONOMY_PAGES block, add <Route path="/taxonomy/:taxonomyId/competencies" element={<CompetencyManagementPage />} /> as a sibling of the existing /taxonomy/:taxonomyId route
Not modified here: src/taxonomy/data/types.ts — the type field is #616's contract to add; this ticket only consumes it.
Implementation Notes
New sibling route under the existing TaxonomyLayout, inheriting its chrome via the existing <Outlet/>, with a deliberately empty-content page. This was chosen over two alternatives: reusing/stubbing the existing TaxonomyDetailPage route (rejected — #622's whole point was to make editing-a-taxonomy and managing-competencies explicitly separate flows, so folding them back into one route would undo that), and a modal mirroring ManageOrgsModal (rejected — the accepted design is a full page with breadcrumbs and, eventually, a taxonomy switcher and tree; that's page-shaped UI, and the future ticket is already named "Competency Management page").
Add one shared predicate (e.g. isCompetencyTaxonomy(taxonomy)) rather than repeating the type comparison in both TaxonomyMenu and TaxonomyCard. #616 should add this predicate as part of shipping the type field, since it needs the same check internally for its badge; this ticket imports it rather than inventing a second one.
This is MFE-only: no backend or openedx-core change, no .importlinter concern, no cross-feature import — everything stays inside the taxonomy feature and is consumed through its own index.ts. No ADR is warranted; this is UI wiring, not a new contract or data model.
Hard dependency, stated plainly: none of this is implementable, demoable, or testable until #616 lands the type field on TaxonomyData and its backend prerequisites (#618, #630) ship first.
Example Resolution Prompt
Implement the "Apply Competencies" entry points on Studio's Taxonomies page in frontend-app-authoring. Prerequisite: the taxonomy-type field and shared predicate that issue #616 adds to TaxonomyData (src/taxonomy/data/types.ts) must exist first — confirm its real name and import #616's predicate rather than inventing a second one; this prompt uses isCompetencyTaxonomy(taxonomy) as a placeholder name.
In src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx, add a 5th entry to the menuItems object after manageOrgs, keyed applyCompetencies: { title: intl.formatMessage(messages.applyCompetenciesMenu), action: () => navigate(\/taxonomy/${taxonomy.id}/competencies`), show: isCompetencyTaxonomy(taxonomy) }. navigateis already available viauseNavigate()in this file. Extend thetaxonomyPropTypes shape and thePick<TaxonomyData, …>` JSDoc.
In src/taxonomy/taxonomy-menu/messages.ts, add applyCompetenciesMenu (id: course-authoring.taxonomy-menu.apply-competencies.label, defaultMessage: 'Apply Competencies').
In src/taxonomy/taxonomy-card/index.jsx, destructure the type field from original, and add a <Card.Footer> (see src/files-and-videos/generic/table-components/GalleryCard.jsx for the existing in-repo Card.Footer pattern) right after <Card.Body>, rendered only when isCompetencyTaxonomy(original), containing <Button as={NavLink} to={\/taxonomy/${id}/competencies`} variant="primary">{intl.formatMessage(messages.applyCompetenciesButton)}`.
In src/taxonomy/taxonomy-card/messages.ts, add applyCompetenciesButton.
Create src/taxonomy/competency-management/ (index.ts, CompetencyManagementPage.tsx, messages.ts, test file). Mirror src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx's data shape (useParams, useTaxonomyDetails(taxonomyId), Loading/ConnectionErrorAlert guards, Breadcrumb). Render only a breadcrumb, a title, and a placeholder body — no TreeView, no taxonomy switcher; those belong to the separate "Competency Management page — initial implementation" ticket.
In src/index.jsx, inside the existing getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true' block, add <Route path="/taxonomy/:taxonomyId/competencies" element={<CompetencyManagementPage />} /> as a sibling of /taxonomy/:taxonomyId; re-export the page from src/taxonomy/index.ts.
Extend TaxonomyMenu.test.tsx and TaxonomyCard.test.jsx with Competency-type and Tag-type fixtures asserting conditional rendering both ways; add CompetencyManagementPage.test.tsx mirroring TaxonomyDetailPage.test.jsx.
Do not touch src/taxonomy/data/types.ts, any backend code, or openedx-core — this ticket only consumes the type field and predicate #616 introduces.
Blocked by: #616, "[FE] Add taxonomy type badge to Taxonomies page" (open, unmerged). #616 owns the
TaxonomyDatafield this ticket's conditional-visibility logic keys off — that field does not exist infrontend-app-authoringtoday. #616 is itself blocked on backend issues #618 and #630 (unmerged). This ticket is ready for development but cannot be implemented, demoed, or tested until #616 lands.Repo:
frontend-app-authoring(Studio MFE). No backend oropenedx-corechange.Use Case
As a Studio Admin or Staff user managing a Competency-type taxonomy, I want an "Apply Competencies" action available directly from the Taxonomies page — as an item in the taxonomy card's actions menu, and as a standalone card-footer button — so that I can navigate straight to that taxonomy's Competency Management page in one click, without confusing this action with the taxonomy tag-editing flow that the unchanged card click already opens.
Description
Current state
Requested change
/taxonomy/:taxonomyId/competencies, and a content-empty placeholder page (breadcrumb + title only) are added as the shared destination, so both entry points land somewhere real and testable.canChangeTaxonomypermission already used for "Manage Organizations" — no new permission tier.Explicitly out of scope
/taxonomy/:taxonomyId/competencies. No operator-facing path produces this URL for a Tag taxonomy; revisit if it becomes a real issue once the destination page has real content.Acceptance Criteria
UX Designs
Figma link
<finalized design image>
Open Questions
TaxonomyDatafor taxonomy type (e.g.taxonomyType: 'tag' | 'competency', ataxonomyClassenum, or a boolean)? This is the literal predicate every conditional in this ticket keys off. Per team decision, coordinate directly with [FE] Add taxonomy type badge to Taxonomies page #616's author now rather than waiting for [FE] Add taxonomy type badge to Taxonomies page #616 to merge, since this ticket is [FE] Add taxonomy type badge to Taxonomies page #616's first real consumer — getting the shape wrong here means revising every file in the Files to Modify table below. Resolve and document the field name as a comment on this ticket before implementation starts; update the Files to Modify table with the real name at that point.Context
frontend-app-authoringHEAD:TaxonomyData(src/taxonomy/data/types.ts:2-18) has no type field today.defineMessagesi18n entries following thecourse-authoring.taxonomy-menu.<action>.labelconvention already used insrc/taxonomy/taxonomy-menu/messages.ts.frontend-app-authoringHEAD:src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx— the existing 4-item menu. Items are a{title, action, show}map (pickBy-filtered), rendered asDropdown.Items.useNavigateis already imported (line 14) but unused; every existingactioncurrently opens a modal viauseToggle. "Apply Competencies" is the first item whoseactionnavigates.src/taxonomy/taxonomy-menu/messages.ts— i18n id convention:course-authoring.taxonomy-menu.<action>.label.src/taxonomy/taxonomy-card/index.jsx— the card:Card.HeadercarriesTaxonomyMenuasactions;Card.Bodyholds the description. NoCard.Footertoday.src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx— the pattern to mirror for the new placeholder page:useParams→useTaxonomyDetails(taxonomyId)→Loading/ConnectionErrorAlertguards →Breadcrumb+Container.src/taxonomy/TaxonomyLayout.tsx— chrome host (Header,StudioFooterSlot,Toast,TaxonomyContext) via<Outlet/>; any sibling route added under it inherits this chrome for free.src/files-and-videos/generic/table-components/GalleryCard.jsx:80-85— existing in-repo precedent for ParagonCard.Footer, confirming it's already a supported, used pattern, just not yet intaxonomy-card.src/index.jsx:104-116— current taxonomy routes, gated bygetConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'.Technical Notes
Files to Create
src/taxonomy/competency-management/index.tsCompetencyManagementPage, per this feature's module-boundary conventionsrc/taxonomy/competency-management/CompetencyManagementPage.tsxuseTaxonomyDetails, empty-state body only — no TreeView/switchersrc/taxonomy/competency-management/messages.tssrc/taxonomy/competency-management/CompetencyManagementPage.test.tsxTaxonomyDetailPage.test.jsx(loading/error/happy path)Files to Modify
src/taxonomy/taxonomy-menu/TaxonomyMenu.jsxmenuItemsentry,applyCompetencies, aftermanageOrgs;actioncalls the already-importednavigate(\/taxonomy/${taxonomy.id}/competencies`);showkeyed off the taxonomy-type field #616 adds (real field name pending — see Open Questions). Extend thetaxonomyPropTypes/JSDocPick<TaxonomyData, …>` to include it.src/taxonomy/taxonomy-menu/messages.tsapplyCompetenciesMenu(id: course-authoring.taxonomy-menu.apply-competencies.label,defaultMessage: 'Apply Competencies')src/taxonomy/taxonomy-menu/TaxonomyMenu.test.tsxsrc/taxonomy/taxonomy-card/index.jsxoriginal; add<Card.Footer>(afterCard.Body) rendered only for Competency-type, containing aButton as={NavLink}to the same route as the menu itemsrc/taxonomy/taxonomy-card/messages.tsapplyCompetenciesButtonmessagesrc/taxonomy/taxonomy-card/TaxonomyCard.test.jsxsrc/index.jsxENABLE_TAGGING_TAXONOMY_PAGESblock, add<Route path="/taxonomy/:taxonomyId/competencies" element={<CompetencyManagementPage />} />as a sibling of the existing/taxonomy/:taxonomyIdroutesrc/taxonomy/index.tsCompetencyManagementPagealongsideTaxonomyDetailPage/TaxonomyListPage/TaxonomyLayoutNot modified here:
src/taxonomy/data/types.ts— the type field is #616's contract to add; this ticket only consumes it.Implementation Notes
New sibling route under the existing
TaxonomyLayout, inheriting its chrome via the existing<Outlet/>, with a deliberately empty-content page. This was chosen over two alternatives: reusing/stubbing the existingTaxonomyDetailPageroute (rejected — #622's whole point was to make editing-a-taxonomy and managing-competencies explicitly separate flows, so folding them back into one route would undo that), and a modal mirroringManageOrgsModal(rejected — the accepted design is a full page with breadcrumbs and, eventually, a taxonomy switcher and tree; that's page-shaped UI, and the future ticket is already named "Competency Management page").Add one shared predicate (e.g.
isCompetencyTaxonomy(taxonomy)) rather than repeating the type comparison in bothTaxonomyMenuandTaxonomyCard. #616 should add this predicate as part of shipping the type field, since it needs the same check internally for its badge; this ticket imports it rather than inventing a second one.This is MFE-only: no backend or
openedx-corechange, no.importlinterconcern, no cross-feature import — everything stays inside thetaxonomyfeature and is consumed through its ownindex.ts. No ADR is warranted; this is UI wiring, not a new contract or data model.Hard dependency, stated plainly: none of this is implementable, demoable, or testable until #616 lands the type field on
TaxonomyDataand its backend prerequisites (#618, #630) ship first.Example Resolution Prompt
Implement the "Apply Competencies" entry points on Studio's Taxonomies page in
frontend-app-authoring. Prerequisite: the taxonomy-type field and shared predicate that issue #616 adds toTaxonomyData(src/taxonomy/data/types.ts) must exist first — confirm its real name and import #616's predicate rather than inventing a second one; this prompt usesisCompetencyTaxonomy(taxonomy)as a placeholder name.src/taxonomy/taxonomy-menu/TaxonomyMenu.jsx, add a 5th entry to themenuItemsobject aftermanageOrgs, keyedapplyCompetencies:{ title: intl.formatMessage(messages.applyCompetenciesMenu), action: () => navigate(\/taxonomy/${taxonomy.id}/competencies`), show: isCompetencyTaxonomy(taxonomy) }.navigateis already available viauseNavigate()in this file. Extend thetaxonomyPropTypes shape and thePick<TaxonomyData, …>` JSDoc.src/taxonomy/taxonomy-menu/messages.ts, addapplyCompetenciesMenu(id: course-authoring.taxonomy-menu.apply-competencies.label,defaultMessage: 'Apply Competencies').src/taxonomy/taxonomy-card/index.jsx, destructure the type field fromoriginal, and add a<Card.Footer>(seesrc/files-and-videos/generic/table-components/GalleryCard.jsxfor the existing in-repoCard.Footerpattern) right after<Card.Body>, rendered only whenisCompetencyTaxonomy(original), containing<Button as={NavLink} to={\/taxonomy/${id}/competencies`} variant="primary">{intl.formatMessage(messages.applyCompetenciesButton)}`.src/taxonomy/taxonomy-card/messages.ts, addapplyCompetenciesButton.src/taxonomy/competency-management/(index.ts,CompetencyManagementPage.tsx,messages.ts, test file). Mirrorsrc/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx's data shape (useParams,useTaxonomyDetails(taxonomyId),Loading/ConnectionErrorAlertguards,Breadcrumb). Render only a breadcrumb, a title, and a placeholder body — no TreeView, no taxonomy switcher; those belong to the separate "Competency Management page — initial implementation" ticket.src/index.jsx, inside the existinggetConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'block, add<Route path="/taxonomy/:taxonomyId/competencies" element={<CompetencyManagementPage />} />as a sibling of/taxonomy/:taxonomyId; re-export the page fromsrc/taxonomy/index.ts.TaxonomyMenu.test.tsxandTaxonomyCard.test.jsxwith Competency-type and Tag-type fixtures asserting conditional rendering both ways; addCompetencyManagementPage.test.tsxmirroringTaxonomyDetailPage.test.jsx.Do not touch
src/taxonomy/data/types.ts, any backend code, oropenedx-core— this ticket only consumes the type field and predicate #616 introduces.