feat: always show song list header action menu (#1869)

This commit is contained in:
Phan An 2024-10-31 16:50:35 +07:00 committed by GitHub
parent 3848e8b52d
commit 5d9d75111a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 10 deletions

View file

@ -70,7 +70,7 @@ new class extends UnitTestCase {
},
global: {
stubs: {
SongListSorter: this.stub('song-list-sorter'),
ActionMenu: this.stub('song-list-header-action-menu'),
},
provide: {
[<symbol>SelectedPlayablesKey]: [ref(selectedPlayables), (value: Playable[]) => (selectedPlayables = value)],

View file

@ -66,8 +66,8 @@
</template>
</span>
<span class="extra">
<SongListSorter
v-if="config.sortable"
<ActionMenu
:sortable="config.sortable"
:field="sortField"
:has-custom-order-sort="config.hasCustomOrderSort"
:order="sortOrder"
@ -87,10 +87,10 @@ import { PlayableListConfigKey, PlayableListSortFieldKey, SongListSortOrderKey }
import type { getPlayableCollectionContentType } from '@/utils/typeGuards'
import { usePlayableListColumnVisibility } from '@/composables/usePlayableListColumnVisibility'
import SongListSorter from '@/components/song/song-list/SongListSorter.vue'
import ActionMenu from '@/components/song/song-list/SongListHeaderActionMenu.vue'
withDefaults(defineProps<{
contentType?: ReturnType<getPlayableCollectionContentType>
contentType?: ReturnType<typeof getPlayableCollectionContentType>
}>(), {
contentType: 'songs',
})

View file

@ -2,7 +2,7 @@ import { screen } from '@testing-library/vue'
import { expect, it } from 'vitest'
import UnitTestCase from '@/__tests__/UnitTestCase'
import { useLocalStorage } from '@/composables/useLocalStorage'
import Component from './SongListSorter.vue'
import Component from './SongListHeaderActionMenu.vue'
new class extends UnitTestCase {
protected test () {
@ -15,6 +15,12 @@ new class extends UnitTestCase {
)
})
it ('emits the sort event when an item is clicked', async () => {
const { emitted } = this.render(Component)
await this.user.click(screen.getByText('Title'))
expect(emitted().sort[0]).toEqual(['title'])
})
it('contains proper items for episode-only lists', () => {
this.render(Component, {
props: {
@ -49,6 +55,17 @@ new class extends UnitTestCase {
screen.getByText('Custom Order')
})
it('does not sort if the list is not sortable', async () => {
const { emitted } = this.render(Component, {
props: {
sortable: false,
},
})
await this.user.click(screen.getByText('Title'))
expect(emitted().sort).toBeUndefined()
})
it('has a checkbox to toggle the column visibility', async () => {
this.be().render(Component)

View file

@ -1,7 +1,8 @@
<template>
<article>
<button ref="button" class="w-full focus:text-k-highlight" title="Sort" @click.stop="trigger">
<Icon :icon="faSort" />
<Icon v-if="sortable" :icon="faSort" />
<Icon v-else :icon="faEllipsis" />
</button>
<OnClickOutside @trigger="hide">
<menu ref="menu" class="context-menu normal-case tracking-normal">
@ -10,7 +11,7 @@
:key="item.label"
:class="currentlySortedBy(item.field) && 'active'"
class="cursor-pointer flex justify-between !pl-3 hover:!bg-white/10"
@click="sort(item.field)"
@click="sortable && sort(item.field)"
>
<label
v-if="shouldShowColumnVisibilityCheckboxes()"
@ -39,7 +40,7 @@
<script lang="ts" setup>
import { isEqual } from 'lodash'
import { faArrowDown, faArrowUp, faCheck, faSort } from '@fortawesome/free-solid-svg-icons'
import { faArrowDown, faArrowUp, faCheck, faEllipsis, faSort } from '@fortawesome/free-solid-svg-icons'
import { OnClickOutside } from '@vueuse/components'
import { computed, onBeforeUnmount, onMounted, ref, toRefs } from 'vue'
import { useFloatingUi } from '@/composables/useFloatingUi'
@ -48,11 +49,13 @@ import type { getPlayableCollectionContentType } from '@/utils/typeGuards'
import { usePlayableListColumnVisibility } from '@/composables/usePlayableListColumnVisibility'
const props = withDefaults(defineProps<{
sortable?: boolean
field?: MaybeArray<PlayableListSortField> // the current field(s) being sorted by
order?: SortOrder
hasCustomOrderSort?: boolean // whether to provide "custom order" sort (like for playlists)
contentType?: ReturnType<typeof getPlayableCollectionContentType>
}>(), {
sortable: true,
field: 'title',
order: 'asc',
hasCustomOrderSort: false,

View file

@ -2,6 +2,6 @@
exports[`renders 1`] = `
<div class="sortable song-list-header flex z-[2] bg-k-bg-secondary pl-5"><span class="track-number" data-testid="header-track-number" role="button" title="Sort by track number"> # <!--v-if--><!--v-if--></span><span class="title-artist" data-testid="header-title" role="button" title="Sort by title"> Title <br data-testid="Icon" icon="[object Object]" class="text-k-highlight"><!--v-if--></span><span title="Sort by album" class="album" data-testid="header-album" role="button">Album<span class="ml-2"><!--v-if--><!--v-if--></span></span>
<!--v-if--><span class="time" data-testid="header-length" role="button" title="Sort by duration"> Time <!--v-if--><!--v-if--></span><span class="extra"><br data-testid="song-list-sorter" field="title" order="asc" content-type="songs"></span>
<!--v-if--><span class="time" data-testid="header-length" role="button" title="Sort by duration"> Time <!--v-if--><!--v-if--></span><span class="extra"><br data-testid="song-list-header-action-menu" sortable="true" field="title" order="asc" content-type="songs"></span>
</div>
`;