Skip to content

Commit 350424a

Browse files
committed
refactor(table-static): sortable behaviour
1 parent 22f211f commit 350424a

File tree

11 files changed

+622
-266
lines changed

11 files changed

+622
-266
lines changed

src/components/table-static/TableStatic.spec.ts

Lines changed: 53 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import Draggable from '../table/__mocks__/vuedraggable'
22
import { vi } from 'vitest'
3-
import { fireEvent, render } from '@testing-library/vue'
4-
import { ref } from 'vue-demi'
3+
import {
4+
render,
5+
fireEvent,
6+
queryByTestId,
7+
} from '@testing-library/vue'
8+
import { nextTick, ref } from 'vue-demi'
59
import { defineTable } from '../table'
610
import Table from './TableStatic.vue'
711

@@ -39,13 +43,10 @@ const items = ref([
3943

4044
const sortableFields = defineTable([
4145
{ key: 'id' },
42-
{
43-
key : 'name',
44-
sortable: true,
45-
},
46+
{ key: 'name' },
4647
{
4748
key : 'gender',
48-
sortable: true,
49+
sortable: false,
4950
},
5051
{
5152
key : 'age',
@@ -358,15 +359,13 @@ it('should able to select all items (except disable one) in variant static', asy
358359
})
359360

360361
it('should X field header have sortable class if have `sortable` property with `true` value & `sortable` prop is provided', () => {
361-
const items = ref([])
362-
items.value = generateItems()
363-
362+
const items = ref(generateItems())
364363
const screen = render({
365364
components: { Table },
366365
template : `
367366
<Table
368367
:fields="sortableFields"
369-
v-model:items="items"
368+
:items="items"
370369
sortable
371370
/>`,
372371
setup () {
@@ -379,181 +378,99 @@ it('should X field header have sortable class if have `sortable` property with `
379378

380379
const heads = screen.queryAllByTestId('table-static-header')
381380

382-
expect(heads.at(0)).not.toHaveClass('table-static__header--sortable')
383-
expect(heads.at(1)).toHaveClass('table-static__header--sortable')
381+
expect(heads.at(0)).toHaveClass('table-static__header--sortable')
382+
expect(heads.at(2)).not.toHaveClass('table-static__header--sortable')
384383
})
385384

386-
it('should X field header have caret up/down icon when sort by field', async () => {
387-
const items = ref([])
388-
items.value = generateItems()
389-
385+
it('should able modify sort by header using v-model:sort-by', async () => {
386+
const items = ref(generateItems())
387+
const sortBy = ref({})
390388
const screen = render({
391389
components: { Table },
392390
template : `
393391
<Table
392+
v-model:sort-by="sortBy"
394393
:fields="sortableFields"
395-
v-model:items="items"
396-
sortable
397-
/>`,
398-
setup () {
399-
return {
400-
sortableFields,
401-
items,
402-
}
403-
},
404-
})
405-
406-
const heads = screen.queryAllByTestId('table-static-header')
407-
408-
await fireEvent.click(heads.at(1))
409-
410-
const sortUp = heads.at(1).querySelector('.table-static__header__sort-up')
411-
412-
expect(sortUp).toBeInTheDocument()
413-
414-
await fireEvent.click(heads.at(1))
415-
416-
const sortDown = heads.at(1).querySelector('.table-static__header__sort-down')
417-
418-
expect(sortDown).toBeInTheDocument()
419-
expect(sortUp).not.toBeInTheDocument()
420-
421-
await fireEvent.click(heads.at(1))
422-
423-
expect(sortDown).not.toBeInTheDocument()
424-
})
425-
426-
it('should able to sort by field if `sortable` prop is provided', async () => {
427-
const items = ref([])
428-
items.value = generateItems()
429-
430-
const sorts = ref([])
431-
432-
const screen = render({
433-
components: { Table },
434-
template : `
435-
<Table
436-
:fields="sortableFields"
437-
v-model:items="items"
394+
:items="items"
438395
sortable
439-
@sort="sorts = $event"
440396
/>`,
441397
setup () {
442398
return {
443399
sortableFields,
444400
items,
445-
sorts,
401+
sortBy,
446402
}
447403
},
448404
})
449405

450-
expect(sorts.value).toHaveLength(0)
451-
452406
const heads = screen.queryAllByTestId('table-static-header')
453407

454-
await fireEvent.click(heads.at(1))
408+
expect(heads.at(0)).toHaveClass('table-static__header--sortable')
409+
expect(heads.at(2)).not.toHaveClass('table-static__header--sortable')
455410

456-
expect(items.value.at(0).name).toStrictEqual('Andi')
457-
expect(sorts.value).toHaveLength(1)
411+
await fireEvent.click(heads.at(0))
458412

459-
await fireEvent.click(heads.at(1))
413+
const icon = queryByTestId(heads[0], 'table-static-header-sort')
460414

461-
expect(items.value.at(0).name).toStrictEqual('Jane')
415+
expect(icon).toHaveAttribute('active', 'asc')
416+
expect(sortBy.value).toStrictEqual({ id: 'asc' })
462417

463-
await fireEvent.click(heads.at(1))
418+
await fireEvent.click(heads.at(0))
464419

465-
expect(items.value.at(0).name).toStrictEqual('Dora')
466-
})
420+
expect(icon).toHaveAttribute('active', 'desc')
421+
expect(sortBy.value).toStrictEqual({ id: 'desc' })
467422

468-
it('should be not sort by field if field not `sortable` eventhough prop `sortable` is provided when render table', async () => {
469-
const fields = defineTable([{ key: 'id' }, { key: 'name' }])
470-
const items = ref([
471-
{
472-
id : 1,
473-
name: 'Jane',
474-
},
475-
{
476-
id : 2,
477-
name: 'Tarjono',
478-
},
479-
])
480-
const sorts = ref([])
481-
482-
const screen = render({
483-
components: { Table },
484-
template : `
485-
<Table
486-
:fields="fields"
487-
v-model:items="items"
488-
sortable
489-
@sort="sorts = $event"
490-
/>`,
491-
setup () {
492-
return {
493-
fields,
494-
items,
495-
sorts,
496-
}
497-
},
498-
})
423+
await fireEvent.click(heads.at(0))
499424

500-
const heads = screen.queryAllByTestId('table-static-header')
425+
expect(icon).not.toHaveAttribute('active', 'desc')
426+
expect(sortBy.value).toStrictEqual({ id: undefined })
501427

502-
await fireEvent.click(heads.at(1))
428+
sortBy.value = { name: 'desc' }
429+
await nextTick()
503430

504-
const sortUp = heads.at(1).querySelector('.table-static__header__sort-up')
431+
const icon2 = queryByTestId(heads[1], 'table-static-header-sort')
505432

506-
expect(sortUp).not.toBeInTheDocument()
507-
expect(sorts.value).toHaveLength(0)
433+
expect(icon).not.toHaveAttribute('active', 'asc')
434+
expect(icon2).toHaveAttribute('active', 'desc')
508435
})
509436

510-
it('should able to sort by field if `sortable` prop is provided', async () => {
511-
const items = ref([])
512-
items.value = generateItems()
513-
514-
const sorts = ref([])
515-
437+
it('should have multiple value if sortable set to `multiple`', async () => {
438+
const items = ref(generateItems())
439+
const sortBy = ref({})
516440
const screen = render({
517441
components: { Table },
518442
template : `
519443
<Table
444+
v-model:sort-by="sortBy"
520445
:fields="sortableFields"
521-
v-model:items="items"
522-
sortable
523-
sortable-asyncronous
524-
@sort="sorts = $event"
446+
:items="items"
447+
sortable="multiple"
525448
/>`,
526449
setup () {
527450
return {
528451
sortableFields,
529452
items,
530-
sorts,
453+
sortBy,
531454
}
532455
},
533456
})
534457

535-
expect(sorts.value).toHaveLength(0)
536-
537458
const heads = screen.queryAllByTestId('table-static-header')
538459

539-
await fireEvent.click(heads.at(2)) // sort gender to ASC
540-
expect(sorts.value).toHaveLength(1)
541-
expect(sorts.value.at(0)).toStrictEqual({ key: 'gender', value: 'asc' })
460+
expect(heads.at(0)).toHaveClass('table-static__header--sortable')
461+
expect(heads.at(2)).not.toHaveClass('table-static__header--sortable')
542462

543-
await fireEvent.click(heads.at(3)) // sort age to ASC
544-
expect(sorts.value).toHaveLength(2)
545-
expect(sorts.value.at(1)).toStrictEqual({ key: 'age', value: 'asc' })
463+
await fireEvent.click(heads.at(0))
546464

547-
await fireEvent.click(heads.at(2)) // sort gender to DESC
548-
expect(sorts.value).toHaveLength(2)
549-
expect(sorts.value.at(0)).toStrictEqual({ key: 'gender', value: 'desc' })
465+
const icon = queryByTestId(heads[0], 'table-static-header-sort')
466+
const icon2 = queryByTestId(heads[1], 'table-static-header-sort')
550467

551-
await fireEvent.click(heads.at(2)) // clear gender sort
552-
expect(sorts.value).toHaveLength(1)
468+
expect(icon).toHaveAttribute('active', 'asc')
469+
expect(sortBy.value).toStrictEqual({ id: 'asc' })
553470

554-
await fireEvent.click(heads.at(3)) // sort age to DESC
555-
expect(sorts.value.at(0)).toStrictEqual({ key: 'age', value: 'desc' })
471+
await fireEvent.click(heads.at(1))
556472

557-
await fireEvent.click(heads.at(3)) // clear age sort
558-
expect(sorts.value).toHaveLength(0)
473+
expect(icon).toHaveAttribute('active', 'asc')
474+
expect(icon2).toHaveAttribute('active', 'asc')
475+
expect(sortBy.value).toStrictEqual({ id: 'asc', name: 'asc' })
559476
})

0 commit comments

Comments
 (0)