Skip to content

Commit d860eff

Browse files
committed
feat(table-sortable-field): add support sortable table by field
1 parent 1287780 commit d860eff

File tree

4 files changed

+495
-8
lines changed

4 files changed

+495
-8
lines changed

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

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,57 @@ const items = ref([
3737
},
3838
])
3939

40+
const sortableFields = defineTable([
41+
{ key: 'id' },
42+
{
43+
key : 'name',
44+
sortable: true,
45+
},
46+
{
47+
key : 'gender',
48+
sortable: true,
49+
},
50+
{
51+
key : 'age',
52+
sortable: true,
53+
},
54+
])
55+
56+
function generateItems () {
57+
return [
58+
{
59+
id : 1,
60+
name : 'Dora',
61+
gender: 'male',
62+
age : 27,
63+
},
64+
{
65+
id : 2,
66+
name : 'Emilly',
67+
gender: 'male',
68+
age : 20,
69+
},
70+
{
71+
id : 3,
72+
name : 'Jane',
73+
gender: 'female',
74+
age : 30,
75+
},
76+
{
77+
id : 4,
78+
name : 'Andi',
79+
gender: 'male',
80+
age : 21,
81+
},
82+
{
83+
id : 5,
84+
name : 'Bella',
85+
gender: 'female',
86+
age : 24,
87+
},
88+
]
89+
}
90+
4091
it('should render properly', () => {
4192
const screen = render({
4293
components: { Table },
@@ -305,3 +356,204 @@ it('should able to select all items (except disable one) in variant static', asy
305356

306357
expect(selected.value).toHaveLength(0)
307358
})
359+
360+
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+
364+
const screen = render({
365+
components: { Table },
366+
template : `
367+
<Table
368+
:fields="sortableFields"
369+
v-model:items="items"
370+
sortable
371+
/>`,
372+
setup () {
373+
return {
374+
sortableFields,
375+
items,
376+
}
377+
},
378+
})
379+
380+
const heads = screen.queryAllByTestId('table-static-header')
381+
382+
expect(heads.at(0)).not.toHaveClass('table-static__header--sortable')
383+
expect(heads.at(1)).toHaveClass('table-static__header--sortable')
384+
})
385+
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+
390+
const screen = render({
391+
components: { Table },
392+
template : `
393+
<Table
394+
: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"
438+
sortable
439+
@sort="sorts = $event"
440+
/>`,
441+
setup () {
442+
return {
443+
sortableFields,
444+
items,
445+
sorts,
446+
}
447+
},
448+
})
449+
450+
expect(sorts.value).toHaveLength(0)
451+
452+
const heads = screen.queryAllByTestId('table-static-header')
453+
454+
await fireEvent.click(heads.at(1))
455+
456+
expect(items.value.at(0).name).toStrictEqual('Andi')
457+
expect(sorts.value).toHaveLength(1)
458+
459+
await fireEvent.click(heads.at(1))
460+
461+
expect(items.value.at(0).name).toStrictEqual('Jane')
462+
463+
await fireEvent.click(heads.at(1))
464+
465+
expect(items.value.at(0).name).toStrictEqual('Dora')
466+
})
467+
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+
})
499+
500+
const heads = screen.queryAllByTestId('table-static-header')
501+
502+
await fireEvent.click(heads.at(1))
503+
504+
const sortUp = heads.at(1).querySelector('.table-static__header__sort-up')
505+
506+
expect(sortUp).not.toBeInTheDocument()
507+
expect(sorts.value).toHaveLength(0)
508+
})
509+
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+
516+
const screen = render({
517+
components: { Table },
518+
template : `
519+
<Table
520+
:fields="sortableFields"
521+
v-model:items="items"
522+
sortable
523+
sortable-asyncronous
524+
@sort="sorts = $event"
525+
/>`,
526+
setup () {
527+
return {
528+
sortableFields,
529+
items,
530+
sorts,
531+
}
532+
},
533+
})
534+
535+
expect(sorts.value).toHaveLength(0)
536+
537+
const heads = screen.queryAllByTestId('table-static-header')
538+
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' })
542+
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' })
546+
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' })
550+
551+
await fireEvent.click(heads.at(2)) // clear gender sort
552+
expect(sorts.value).toHaveLength(1)
553+
554+
await fireEvent.click(heads.at(3)) // sort age to DESC
555+
expect(sorts.value.at(0)).toStrictEqual({ key: 'age', value: 'desc' })
556+
557+
await fireEvent.click(heads.at(3)) // clear age sort
558+
expect(sorts.value).toHaveLength(0)
559+
})

0 commit comments

Comments
 (0)