learningequality / learningequality/studio
[Remove Vuetify from Studio] Replace LanguageDropdown VAutocomplete with KDS KMultiSelect
@adibmbrk is already working on this.
Since Sep 17, 2026.
- Dominant language
- Python
- Stars
- 191
- Forks
- 307
- Avg merge
- 5d 6h
- Merged PRs (30d)
- 10
Description
🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:
- Read Contributing guidelines carefully. Pay extra attention to Using generative AI. Pull requests and comments that don’t follow the guidelines won’t be answered.
- Confirm that you’ve read the guidelines in your comment.
Overview
LanguageDropdown uses the Vuetify component VAutocomplete. Replace it with KMultiSelect from the Kolibri Design System.
Complexity: Medium
Target branch: unstable
Context
File: contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vue
The component wraps VAutocomplete in DropdownWrapper. It shows a tooltip on each option. It validates with the Vuetify rules prop. It has style overrides that use ::v-deep.
Six files use this component:
| File | What it needs |
|---|---|
channelEdit/components/edit/DetailsTabView.vue |
Shows hint text below the field |
channelEdit/views/files/supplementaryLists/SupplementaryList.vue |
Hides languages with excludeLanguages |
channelEdit/views/ImportFromChannels/SearchFilters.vue |
Selects more than one language |
channelEdit/views/ImportFromChannels/ChannelList.vue |
Selects one language |
shared/views/channel/ChannelModal.vue |
Makes the field required |
administration/pages/Channels/ChannelTable.vue |
Reads the languages list from the component with a template ref |
Key things to know before you start:
KMultiSelectuses the propsinvalidandinvalidText. It does not use the Vuetifyrulesprop.- A Vuetify
VFormcannot validate aKMultiSelect.ChannelModalneeds a language, so it needs another way to validate the field. Studio already has a pattern for this. The field adds a publicvalidate()method, and the parent calls it.ExpandableSelect.vueandMasteryCriteriaGoal.vueboth do this.CompletionOptions/index.vueis an example of how a parent calls it. - The
languageTextmethod returns early for arrays. A comment explains why. This works around aVAutocompletebehavior.
The tests in shared/views/__tests__/languageDropdown.spec.js use @vue/test-utils, but Studio no longer writes new tests with it.
The Change
LanguageDropdownrendersKMultiSelect. It keeps the propsvalue,required,excludeLanguagesandmultiple, so the six files change as little as possible.- Search must still find a language by its native name, its English name or its code. Use the
searchKeysprop. - The accessibility strings in
messagescome fromshared/strings/commonStrings.js. Add a string to$trsonly when no shared string exists. - Remove
DropdownWrapper, the tooltip template and the::v-deepstyles. Set the field width withappearanceOverrides. LanguageDropdowngets a publicvalidate()method that returns the error text, andChannelModalcalls it next tothis.$refs.detailsform.validate(). A user must not save a channel without a language.- Remove the early return for arrays in
languageTextand its comment. - Remove the Vuetify props from the six files, such as
box,hide-details,persistent-hintanddropAbove.KMultiSelecthas no hint prop, soDetailsTabViewneeds another way to show its hint text.
How to Get There
- Required field: Channel list, open a channel, Edit channel details. Clear the language and save.
- Hint text: Channel editor, select a resource, Edit, Details tab, Audience, Language.
- More than one language: Channel editor, Add, Import from channels, Search filters, Language.
- Hidden languages: Channel editor, select a video or audio resource, Edit, Files, add a caption file.
- Filter: Administration, Channels, Language filter.
Out of Scope
- The other Vuetify components in the six files.
- The
VForminChannelModaland inDetailsTabView. Only the language field changes.
Acceptance Criteria
General
-
LanguageDropdown.vuerendersKMultiSelect. It has noVAutocomplete, noVTooltipand noDropdownWrapper. - Single selection and multiple selection both work. The
inputevent sends the same value as before in all six files. -
excludeLanguagesstill hides languages. -
ChannelModaldoes not save a channel when the language is empty, and the field shows the error text. - The language filter in
ChannelTablestill shows its options. - The six files no longer pass Vuetify props to the component.
-
DetailsTabViewstill shows its hint text. - The early return for arrays in
languageTextis gone.
Accessibility and i18n
-
messageshas every key thatKMultiSelectneeds. Shared strings come fromcommonStrings.js. - Every new text string goes through
$trsor a shared translator. - A keyboard user can open the list, type to filter it, move through the options, select an option and clear the field.
- All colors come from theme tokens.
Testing
-
languageDropdown.spec.jsuses Vue Testing Library. - A test covers the empty language error in
ChannelModal. -
pnpm testpasses. -
pre-commit run --all-filespasses.
References
- KMultiSelect documentation
contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vue
AI usage
I used Claude Code to draft this issue. It read the component and listed the files that use it. I reviewed the file references and edited the text.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.