Skip to content

[FE] Add Taxonomy Type dropdown to taxonomy import flow #615

Closed

Description

@mgwozdz-unicon

Use Case

As a Platform Administrator, I need to select a Taxonomy Type when importing a taxonomy so that the platform correctly stores the imported taxonomy as a Competency Taxonomy or a standard tag taxonomy.


Description

Today, the taxonomy import workflow in Studio follows these steps:

  1. Log in to Studio as an Admin or Staff user.
  2. Click on the Taxonomies tab.
  3. Click the Import button.
  4. Upload a JSON or CSV file in the required template format.
  5. Click Continue.
  6. The modal advances to a "Populate Taxonomy Information" step with two fields: Taxonomy Name and Taxonomy Description.
  7. Click Import to complete the process.

This issue adds a Taxonomy Type dropdown to step 6, beneath the existing Description field. The dropdown offers two user-selectable options: "Tags" (default) and "Competency". A third type ("System") is reserved for platform use and must not appear as a selectable option. The selected value is sent to the taxonomy import API endpoint as part of the import request when the user clicks Import in step 7.

This ticket covers the dropdown UI, form state, and API payload only. Displaying the taxonomy type in the taxonomy list or detail views is out of scope and will be addressed in a future ticket (#616). Until that display ticket ships, QA must verify backend storage of the taxonomy type via Postman.

Dependency: The import endpoint's support for taxonomy_type is implemented in #614. That ticket must be merged before this frontend change can be verified end-to-end. The Postman-based GET verification in Acceptance Criteria (Scenarios 2 and 3) additionally depends on #618, which adds taxonomy_type to the GET response.


Acceptance Criteria

Displaying the taxonomy type in the list or detail views is out of scope. Backend storage must be verified via Postman until the display ticket ships.

Scenario 1: Dropdown appears in the correct modal step with correct options
  Given the user has uploaded a taxonomy file and advanced to the "Populate Taxonomy Information" step
  Then a "Taxonomy Type" dropdown is visible below the Description field
  And "Tags" is selected by default
  And "Tags" and "Competency" are the only options in the dropdown
  And "System" is not present as an option
  And the dropdown label and option strings are rendered through the existing i18n message system (useIntl / intl.formatMessage), not hardcoded
  And the dropdown has a properly associated <label> and aria-* attributes consistent with the other fields in the wizard

Scenario 2: Importing with Competency type selected
  Given the user is on the "Populate Taxonomy Information" step
  And the user selects "Competency" from the Taxonomy Type dropdown
  When the user clicks "Import"
  Then the import completes successfully
  And the new taxonomy appears in the taxonomy list
  And [Postman, requires #618 merged] GET the new taxonomy returns taxonomy_type = "competency"

Scenario 3: Importing with Tags type (default or explicit selection)
  Given the user is on the "Populate Taxonomy Information" step
  And the Taxonomy Type dropdown is left at its default or set explicitly to "Tags"
  When the user clicks "Import"
  Then the import completes successfully
  And the new taxonomy appears in the taxonomy list
  And [Postman, requires #618 merged] GET the new taxonomy returns taxonomy_type = "tags"

UX Designs

Figma Link

Image

Technical Notes

Files to Create

None expected.

Modified Files

File Nature of modification
src/taxonomy/import-tags/ImportTagsWizard.jsx Add Taxonomy Type dropdown to PopulateStep; extend taxonomyPopulateData state
src/taxonomy/data/apiHooks.ts Add taxonomy_type to the FormData POST payload in useImportNewTaxonomy
src/taxonomy/data/types.ts Add taxonomyType to the relevant request payload type if one exists
src/taxonomy/import-tags/messages.js (confirm exact path) Add i18n message definitions for the "Taxonomy Type" label and "Tags"/"Competency" option strings
src/taxonomy/data/apiHooks.test.ts (confirm exact path) Add a unit test asserting taxonomy_type is included in the FormData payload for both dropdown selections

Implementation Notes

  • Dropdown placement: The PopulateStep component (lines 183–220 of ImportTagsWizard.jsx) renders the Name and Description fields. Add the Taxonomy Type dropdown directly below the Description textarea, using the same UI component library patterns already present in the file. Options: "Tags" (default) and "Competency" only — do not include "System".
  • State: The taxonomyPopulateData state (lines 305–308) currently holds { taxonomyName, taxonomyDesc }. Extend it with taxonomyType: 'tags' as the default. The existing change handler pattern (lines 189–199) works with an additional field without restructuring.
  • API payload: The useImportNewTaxonomy hook (lines 113–137 of apiHooks.ts) builds FormData and POSTs to createTaxonomyFromImport() (defined at api.ts:95). Always append taxonomy_type to the FormData — send "competency" or "tags" depending on the dropdown selection. The backend accepts both values explicitly; do not omit the field.
  • i18n: The dropdown label ("Taxonomy Type") and option strings ("Tags", "Competency") must go through the existing i18n infrastructure (useIntl() / intl.formatMessage()), matching the pattern already used for the Name and Description fields in ImportTagsWizard.jsx. Do not hardcode these strings; this is a required step, not optional.
  • Accessibility: The dropdown needs a properly associated <label> and aria-* attributes consistent with the existing form fields in the wizard. The paragon Select/Form component likely handles this by default — verify it does, don't assume.
  • Testing: Add a unit test for useImportNewTaxonomy asserting taxonomy_type is present in the submitted FormData for both the "tags" and "competency" selections.
  • No new components needed. The dropdown should reuse existing Select/Form patterns already present in the file.

Example Resolution Prompt

In frontend-app-authoring, update the taxonomy import modal to add a Taxonomy Type dropdown. In src/taxonomy/import-tags/ImportTagsWizard.jsx, add a dropdown to the PopulateStep component (currently lines 183–220) below the Description textarea. Options: "Tags" (default) and "Competency" — do not include "System". Extend the taxonomyPopulateData state (currently lines 305–308) with taxonomyType: 'tags'. Route the dropdown's label and option strings through the existing useIntl() / intl.formatMessage() i18n infrastructure — do not hardcode them — and add the corresponding message definitions. Ensure the dropdown has a properly associated <label> and aria-* attributes consistent with the wizard's other fields. In src/taxonomy/data/apiHooks.ts, update useImportNewTaxonomy (lines 113–137) to always append taxonomy_type to the FormData sent to createTaxonomyFromImport(): send "competency" or "tags" based on the dropdown selection, and add a unit test asserting this field is present in the payload for both selections. Match the existing component and state-management patterns already in the file.

Activity

  1. changed the title [-]Add Taxonomy Type dropdown to taxonomy import flow[/-] [+][FE] Add Taxonomy Type dropdown to taxonomy import flow[/+] on Jun 30, 2026
  2. jesperhodge commented on Jul 1, 2026

    @jesperhodge
    Contributor

    Claude-supported feedback:

    • AC Scenario 3 says "GET the new taxonomy returns taxonomy_type = null" (via Postman). This is testing the GET endpoint which is a dependency from [BE] Update Get endpoint to return Taxonomy Type. #618, not from [BE] Update taxonomy Create & Import endpoints to accept Taxonomy Type #614. The AC should say that this Postman verification requires [BE] Update Get endpoint to return Taxonomy Type. #618 to be merged first, or it should be removed as a verification step from this ticket.
    • i18n is not mentioned. The dropdown label strings "Tags" and "Competency" need to go through the i18n infrastructure. The existing file presumably uses useIntl() and intl.formatMessage(). This is a required step, not optional.
    • Accessibility not mentioned. The dropdown needs a proper association and aria-* attributes consistent with the form patterns already in ImportTagsWizard.jsx. This is likely handled by using the paragon component, but it should be an AC that is tested to confirm it's in place.
    • The hook change in apiHooks.ts needs a unit test for the taxonomy_type payload.
  3. jesperhodge commented on Jul 1, 2026

    @jesperhodge
    Contributor

    When design is ready, let's add screenshots and keep them up to date.

  4. self-assigned this
    on Jul 1, 2026
  5. illiphilli commented on Jul 1, 2026

    @illiphilli

    Here's the updated Taxonomy Detail view with the Taxonomy Type select menu.

    Figma Link

    Image
  6. mgwozdz-unicon commented on Jul 1, 2026

    @mgwozdz-unicon
    ContributorAuthor

    Note that #614 is the backend counterpart to this ticket.

  7. mgwozdz-unicon commented on Jul 2, 2026

    @mgwozdz-unicon
    ContributorAuthor

    @jesperhodge Addressing your feedback above, updated the ticket description to match:

    On Scenario 3 testing the GET endpoint (a #618 dependency, not #614's): agreed, and the same issue applied to Scenario 2's Postman check for the same reason, so I fixed both. Each now explicitly notes it requires #618 merged. I also corrected Scenario 3's expected value from taxonomy_type = null to taxonomy_type = "tags", since the null-default was changed to "tags" as part of #618's revision — leaving null here would've been stale once that ships. Added the #618 dependency to the Description's Dependency line as well, alongside the existing #614 dependency.

    On i18n: added it as a requirement, not just a note. The dropdown label and option strings now have an explicit AC in Scenario 1 (rendered through useIntl() / intl.formatMessage(), not hardcoded), an implementation note calling out the existing pattern in ImportTagsWizard.jsx to follow, and a Files to Modify entry for the messages file.

    On accessibility: added as an AC per your suggestion — Scenario 1 now includes a clause requiring a properly associated <label> and aria-* attributes consistent with the wizard's other fields, plus an implementation note to verify the paragon Select/Form component provides this rather than assuming it does.

    On the missing unit test for apiHooks.ts: added a Files to Modify entry and an implementation note requiring a unit test asserting taxonomy_type is present in the FormData payload for both the "tags" and "competency" selections.

    Full updated ticket description reflects all of this.

  8. moved this from Todo to Ready for Community Review in Competency Criteria and Student Progresson Jul 2, 2026
  9. 15 remaining items

  10. moved this from Next Sprint to In Progress in Competency Criteria and Student Progresson Aug 25, 2026
  11. moved this from In Progress to Code Review in Competency Criteria and Student Progresson Aug 28, 2026
  12. moved this from Unicon Code Review to Community Code Review in Competency Criteria and Student Progresson Sep 3, 2026
  13. moved this from Community Code Review to Ready for QA in Competency Criteria and Student Progresson Sep 18, 2026
  14. dvarenikqaconsultant commented on Sep 22, 2026

    @dvarenikqaconsultant

    Environment: Master Sandbox (https://apps.master.openedx.io/authoring/home)
    Test user: dmitryvarenikqa
    Test type: UI (Studio, taxonomy import wizard) + API (Postman, for backend verification of taxonomy_type)
    Overall result: All three acceptance criteria scenarios pass. One unrelated, pre-existing bug was found during testing; it is being filed as a separate ticket with an Out of Scope status and does not block this ticket.

    Image

    Scenario 1: Dropdown appears in the correct modal step, with the correct options

    • The "Taxonomy Type" dropdown appears in the "Populate Taxonomy Information" step, directly below the Description field.

    • "Tags" is selected by default.

    • The dropdown offers exactly two options, "Tags" and "Competency". "System" is not present as an option.

    • A selection is required; the wizard does not allow proceeding without one (the default satisfies this in practice, since the field is never empty).

    • The label and both option strings ("Taxonomy Type", "Tags", "Competency") are rendered through the existing i18n message system (useIntl / intl.formatMessage), the same pattern used by every other field in the wizard. No hardcoded label or option text was found in the component source. Confirmed directly in the source:

      src/taxonomy/import-tags/messages.ts:

      importWizardStepPopulateTaxonomyType: {
        id: 'course-authoring.import-tags.wizard.step-populate.type',
        defaultMessage: 'Taxonomy Type',
      },
      importWizardStepPopulateTaxonomyTypeTags: {
        id: 'course-authoring.import-tags.wizard.step-populate.type.tags',
        defaultMessage: 'Tags',
      },
      importWizardStepPopulateTaxonomyTypeCompetency: {
        id: 'course-authoring.import-tags.wizard.step-populate.type.competency',
        defaultMessage: 'Competency',
      },

      src/taxonomy/import-tags/steps/PopulateStep.tsx:

      <Form.Label>
        {intl.formatMessage(messages.importWizardStepPopulateTaxonomyType)}
      </Form.Label>
      ...
      {TAXONOMY_TYPE_OPTIONS.map(({ value, message }) => (
        <option key={value} value={value}>
          {intl.formatMessage(message)}
        </option>
      ))}
    • The dropdown has a properly associated label, consistent with the Name and Description fields above it: all three fields use the native <label for="form-fieldN"> / id="form-fieldN" pairing, and the accessibility tree resolves the same way for all three (accessible name matches the visible label text). None of the three fields carries aria-label, aria-labelledby, or aria-describedby, so the dropdown's lack of those attributes is consistent with the rest of the wizard, not a gap specific to this field.

    • Regression on the surrounding fields: the wizard cannot be advanced without uploading a file, and the import cannot be completed without both Taxonomy Name and Taxonomy Description filled in. Both checks behave as expected with the new field added.

    • The selected taxonomy type is retained on the created taxonomy after import completes (verified via the Postman checks in Scenarios 2 and 3 below, since the type is not yet surfaced in the taxonomy list or detail UI).

    Scenario 2: Importing with Competency type selected

    • Selected "Competency" in the Taxonomy Type dropdown, then completed the import.
    • The import completed successfully and the new taxonomy appeared in the taxonomy list.
    • Postman: GET the newly created taxonomy returned taxonomy_type: "competency".

    Scenario 3: Importing with Tags type (default or explicit)

    • Left the Taxonomy Type dropdown at its default ("Tags"), then completed the import.
    • The import completed successfully and the new taxonomy appeared in the taxonomy list.
    • Postman: GET the newly created taxonomy returned taxonomy_type: "tags".

    Observation: dropdown not translated when switching language (not a bug)

    Switching the openedx-language-preference cookie to ru translates the rest of the page but not the new "Taxonomy Type" label or its option strings. Source inspection confirms these strings are wired through the standard i18n message system, not hardcoded, so this is not a defect against this ticket's acceptance criteria. Confirmation was received that shipping complete translations for new strings is not a requirement for this ticket; that is handled separately through the normal translation-sync process.

    Additionally tested: pre-existing bug found (Out of Scope)

    While testing the import flow, a bug was found in the "Continue" button on the Upload step of the wizard: after successfully completing the Upload step once, closing the wizard, reopening it, and uploading a previously used file again, clicking "Continue" does nothing. No error is shown and no step change occurs; only a full page reload restores normal behavior. The bug reproduces reliably on every subsequent reopen with a previously used file.

    This behavior traces to code that predates this ticket (the Upload step's button logic, the useImportPlan hook, and the shared LoadingButton component are all unchanged by this ticket's diff), so it is not a regression introduced here. It is being filed as its own ticket with an Out of Scope status: #827.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions