-
Notifications
You must be signed in to change notification settings - Fork 297
Fix channels admin filters #5742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from all commits
429975a
e01eee1
22478ad
3c6342c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,13 +5,13 @@ | |
| {{ `${$formatNumber(count)} ${count === 1 ? 'channel' : 'channels'}` }} | ||
| </h1> | ||
| <VLayout | ||
| rowwrap | ||
| wrap | ||
| class="mb-2" | ||
| > | ||
| <VFlex | ||
| xs12 | ||
| sm4 | ||
| xl3 | ||
| sm6 | ||
| md3 | ||
| class="px-3" | ||
| > | ||
| <VSelect | ||
|
|
@@ -21,14 +21,13 @@ | |
| item-value="key" | ||
| label="Channel Type" | ||
| box | ||
| clearable | ||
| :menu-props="{ offsetY: true }" | ||
| /> | ||
| </VFlex> | ||
| <VFlex | ||
| xs12 | ||
| sm4 | ||
| xl3 | ||
| sm6 | ||
| md3 | ||
| clearable | ||
| class="px-3" | ||
| > | ||
|
|
@@ -45,8 +44,8 @@ | |
| </VFlex> | ||
| <VFlex | ||
| xs12 | ||
| sm4 | ||
| xl3 | ||
| sm6 | ||
| md3 | ||
| class="px-3" | ||
| > | ||
| <LanguageDropdown | ||
|
|
@@ -56,8 +55,8 @@ | |
| </VFlex> | ||
| <VFlex | ||
| xs12 | ||
| sm4 | ||
| xl3 | ||
| sm6 | ||
| md3 | ||
| class="px-3" | ||
| > | ||
| <VTextField | ||
|
|
@@ -154,11 +153,29 @@ | |
| import Checkbox from 'shared/views/form/Checkbox'; | ||
| import IconButton from 'shared/views/IconButton'; | ||
| import LanguageDropdown from 'shared/views/LanguageDropdown'; | ||
| import { CommunityLibraryStatus } from 'shared/constants'; | ||
|
|
||
| const ChannelTypeFilter = { | ||
| ALL: 'all', | ||
| KOLIBRI_LIBRARY: 'kolibriLibrary', | ||
| COMMUNITY_LIBRARY: 'communityLibrary', | ||
| UNLISTED: 'unlisted', | ||
| }; | ||
|
|
||
| const channelTypeFilterMap = { | ||
| kolibriStudio: { label: 'Kolibri Studio Library', params: { public: true, deleted: false } }, | ||
| community: { label: 'Community Library', params: { has_community_library_submission: true } }, | ||
| unlisted: { | ||
| [ChannelTypeFilter.ALL]: { | ||
| label: 'All Channels', | ||
| params: {}, | ||
| }, | ||
| [ChannelTypeFilter.KOLIBRI_LIBRARY]: { | ||
| label: 'Kolibri Studio Library', | ||
| params: { public: true, deleted: false }, | ||
| }, | ||
| [ChannelTypeFilter.COMMUNITY_LIBRARY]: { | ||
| label: 'Community Library', | ||
| params: { has_community_library_submission: true }, | ||
| }, | ||
| [ChannelTypeFilter.UNLISTED]: { | ||
| label: 'Unlisted Channels', | ||
| params: { has_community_library_submission: false, public: false }, | ||
| }, | ||
|
|
@@ -178,30 +195,41 @@ | |
| const store = proxy.$store; | ||
|
|
||
| const statusFilterMap = computed(() => { | ||
| if (channelTypeFilter.value === 'kolibriStudio') { | ||
| if (channelTypeFilter.value === ChannelTypeFilter.KOLIBRI_LIBRARY) { | ||
| return { | ||
| live: { label: 'Live', params: {} }, | ||
| cheffed: { label: 'Sushi chef', params: { cheffed: true } }, | ||
| }; | ||
| } else if (channelTypeFilter.value === 'community') { | ||
| } else if (channelTypeFilter.value === ChannelTypeFilter.COMMUNITY_LIBRARY) { | ||
| return { | ||
| live: { label: 'Live', params: { community_library_live: true } }, | ||
| needsReview: { | ||
| label: 'Needs review', | ||
| params: { | ||
| community_library_live: false, | ||
| latest_community_library_submission_status: ['PENDING', 'REJECTED'], | ||
| latest_community_library_submission_status: [ | ||
| CommunityLibraryStatus.PENDING, | ||
| CommunityLibraryStatus.REJECTED, | ||
| ], | ||
| }, | ||
| }, | ||
| published: { label: 'Published', params: {} }, | ||
| cheffed: { label: 'Sushi chef', params: { cheffed: true } }, | ||
| }; | ||
| } else if (channelTypeFilter.value === 'unlisted') { | ||
| } else if (channelTypeFilter.value === ChannelTypeFilter.UNLISTED) { | ||
| return { | ||
| live: { label: 'Live', params: {} }, | ||
| draft: { label: 'Draft', params: { published: false } }, | ||
| published: { label: 'Published', params: { published: true } }, | ||
| cheffed: { label: 'Sushi chef', params: { cheffed: true } }, | ||
| live: { label: 'Live', params: { deleted: false } }, | ||
| draft: { label: 'Draft', params: { published: false, deleted: false } }, | ||
| published: { label: 'Published', params: { published: true, deleted: false } }, | ||
| cheffed: { label: 'Sushi chef', params: { cheffed: true, deleted: false } }, | ||
| deleted: { label: 'Deleted', params: { deleted: true } }, | ||
| }; | ||
| } else if (channelTypeFilter.value === ChannelTypeFilter.ALL) { | ||
| return { | ||
| live: { label: 'Live', params: { deleted: false } }, | ||
| published: { label: 'Published', params: { published: true, deleted: false } }, | ||
| draft: { label: 'Draft', params: { published: false, deleted: false } }, | ||
| cheffed: { label: 'Sushi chef', params: { cheffed: true, deleted: false } }, | ||
| deleted: { label: 'Deleted', params: { deleted: true } }, | ||
| }; | ||
| } | ||
| return {}; | ||
|
|
@@ -230,7 +258,9 @@ | |
| } = useFilter({ | ||
| name: 'channelType', | ||
| filterMap: channelTypeFilterMap, | ||
| defaultValue: ChannelTypeFilter.ALL, | ||
| }); | ||
|
|
||
| // Temporal wrapper, must be removed after migrating to KSelect | ||
| const channelTypeFilter = computed({ | ||
| get: () => _channelTypeFilter.value.value || undefined, | ||
|
|
@@ -281,10 +311,14 @@ | |
| fetchQueryParams: keywordSearchFetchQueryParams, | ||
| } = useKeywordSearch(); | ||
|
|
||
| watch(channelTypeFilter, () => { | ||
| const options = channelStatusOptions.value; | ||
| channelStatusFilter.value = options.length ? options[0].value : null; | ||
| }); | ||
| watch( | ||
| channelTypeFilter, | ||
| () => { | ||
| const options = channelStatusOptions.value; | ||
| channelStatusFilter.value = options.length ? options[0].value : null; | ||
| }, | ||
| { immediate: true }, | ||
| ); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. praise: Adding |
||
|
|
||
| const filterFetchQueryParams = computed(() => { | ||
| return { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,17 +34,18 @@ import { useQueryParams } from './useQueryParams'; | |
| * @param {Object} params The parameters for the filter. | ||
| * @param {string} params.name The name of the filter used in query params. | ||
| * @param {Object} params.filterMap A map of available filters. | ||
| * @param {string|null} [params.defaultValue] Optional default value if query param is not set. | ||
| * @returns {UseFilterReturn} | ||
| */ | ||
| export function useFilter({ name, filterMap }) { | ||
| export function useFilter({ name, filterMap, defaultValue = null }) { | ||
| const route = useRoute(); | ||
| const { updateQueryParams } = useQueryParams(); | ||
|
|
||
| const filter = computed({ | ||
| get: () => { | ||
| const routeFilter = route.query[name]; | ||
| const filterOption = options.value.find(option => option.value === routeFilter); | ||
| return filterOption || {}; | ||
| return filterOption || options.value.find(option => option.value === defaultValue) || {}; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. praise: Clean fallback chain — try the route query param first, then the default value, then empty object. Minimal change that adds |
||
| }, | ||
| set: value => { | ||
| updateQueryParams({ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Good use of a
ChannelTypeFilterenum to replace the previous magic strings ('kolibriStudio','community','unlisted'). This makes the filter logic easier to follow and less error-prone.