
馃檪 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you鈥檙e requesting an issue, please:
- Read Contributing guidelines carefully. Pay extra attention to Using generative AI. Pull requests and comments that don鈥檛 follow the guidelines won鈥檛 be answered.
- Confirm that you鈥檝e 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:
KMultiSelect uses the props invalid and invalidText. It does not use the Vuetify rules prop.
- A Vuetify
VForm cannot validate a KMultiSelect. ChannelModal needs a language, so it needs another way to validate the field. Studio already has a pattern for this. The field adds a public validate() method, and the parent calls it. ExpandableSelect.vue and MasteryCriteriaGoal.vue both do this. CompletionOptions/index.vue is an example of how a parent calls it.
- The
languageText method returns early for arrays. A comment explains why. This works around a VAutocomplete behavior.
The tests in shared/views/__tests__/languageDropdown.spec.js use @vue/test-utils, but Studio no longer writes new tests with it.
The Change
LanguageDropdown renders KMultiSelect. It keeps the props value, required, excludeLanguages and multiple, 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
searchKeys prop.
- The accessibility strings in
messages come from shared/strings/commonStrings.js. Add a string to $trs only when no shared string exists.
- Remove
DropdownWrapper, the tooltip template and the ::v-deep styles. Set the field width with appearanceOverrides.
LanguageDropdown gets a public validate() method that returns the error text, and ChannelModal calls it next to this.$refs.detailsform.validate(). A user must not save a channel without a language.
- Remove the early return for arrays in
languageText and its comment.
- Remove the Vuetify props from the six files, such as
box, hide-details, persistent-hint and dropAbove. KMultiSelect has no hint prop, so DetailsTabView needs 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
VForm in ChannelModal and in DetailsTabView. Only the language field changes.
Acceptance Criteria
General
Accessibility and i18n
Testing
References
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.
馃檪 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you鈥檙e requesting an issue, please:
Overview
LanguageDropdownuses the Vuetify componentVAutocomplete. Replace it withKMultiSelectfrom the Kolibri Design System.Complexity: Medium
Target branch: unstable
Context
File:
contentcuration/contentcuration/frontend/shared/views/LanguageDropdown.vueThe component wraps
VAutocompleteinDropdownWrapper. It shows a tooltip on each option. It validates with the Vuetifyrulesprop. It has style overrides that use::v-deep.Six files use this component:
channelEdit/components/edit/DetailsTabView.vuechannelEdit/views/files/supplementaryLists/SupplementaryList.vueexcludeLanguageschannelEdit/views/ImportFromChannels/SearchFilters.vuechannelEdit/views/ImportFromChannels/ChannelList.vueshared/views/channel/ChannelModal.vueadministration/pages/Channels/ChannelTable.vuelanguageslist from the component with a template refKey things to know before you start:
KMultiSelectuses the propsinvalidandinvalidText. It does not use the Vuetifyrulesprop.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.languageTextmethod returns early for arrays. A comment explains why. This works around aVAutocompletebehavior.The tests in
shared/views/__tests__/languageDropdown.spec.jsuse@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.searchKeysprop.messagescome fromshared/strings/commonStrings.js. Add a string to$trsonly when no shared string exists.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.languageTextand its comment.box,hide-details,persistent-hintanddropAbove.KMultiSelecthas no hint prop, soDetailsTabViewneeds another way to show its hint text.How to Get There
Out of Scope
VForminChannelModaland inDetailsTabView. Only the language field changes.Acceptance Criteria
General
LanguageDropdown.vuerendersKMultiSelect. It has noVAutocomplete, noVTooltipand noDropdownWrapper.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.ChannelTablestill shows its options.DetailsTabViewstill shows its hint text.languageTextis gone.Accessibility and i18n
messageshas every key thatKMultiSelectneeds. Shared strings come fromcommonStrings.js.$trsor a shared translator.Testing
languageDropdown.spec.jsuses Vue Testing Library.ChannelModal.pnpm testpasses.pre-commit run --all-filespasses.References
contentcuration/contentcuration/frontend/channelList/views/Channel/components/LanguageFilter.vueAI 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.