Skip to content

Commit

Permalink
feat: [table] fix #248 -sorting feature- refacto & tests/docs updated
Browse files Browse the repository at this point in the history
  • Loading branch information
mattgoud committed Nov 29, 2023
1 parent 4599750 commit 8952292
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 29 deletions.
9 changes: 6 additions & 3 deletions packages/components/table/src/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ export interface PuikTableHeader {
sortable?: boolean
}

export type ServerSortOption = {
// page: number
// rowsPerPage: number
export type sortOption = {
sortBy?: string
sortOrder?: PuikTableSortOrder
}
Expand Down Expand Up @@ -60,6 +58,11 @@ export const tableProps = buildProps({
required: false,
default: () => [],
},
sortFromServer: {
type: Boolean,
required: false,
default: false,
},
fullWidth: {
type: Boolean,
required: false,
Expand Down
96 changes: 74 additions & 22 deletions packages/components/table/src/table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,7 @@
</tr>
</thead>
<tbody class="puik-table__body">
<template
v-for="(item, rowIndex) in sortedItems"
:key="`row-${rowIndex}`"
>
<template v-for="(item, rowIndex) in data" :key="`row-${rowIndex}`">
<tr class="puik-table__body__row">
<td
v-if="selectable || expandable"
Expand Down Expand Up @@ -176,17 +173,63 @@
class="puik-table__body__row--expanded"
>
<td
:colspan="headers.length"
class="puik-table__body__row__item--expanded"
v-if="stickyFirstCol"
:class="[
'puik-table__body__row__item puik-table__body__row__item--selection',
{ 'puik-table__body__row__item--sticky': stickyFirstCol },
{
'puik-table__body__row__item--sticky-scroll':
stickyFirstCol &&
ScrollBarPosition ==
PuikTableScrollBarPosistion.ISSCROLLING,
},
{
'puik-table__body__row__item--sticky-left':
stickyFirstCol &&
ScrollBarPosition == PuikTableScrollBarPosistion.LEFT,
},
{
'puik-table__body__row__item--sticky-right':
stickyFirstCol &&
ScrollBarPosition == PuikTableScrollBarPosistion.RIGHT,
},
]"
></td>
<td
:colspan="
stickyFirstCol && stickyLastCol
? headers.length - 1
: headers.length
"
class="puik-table__body__row__item puik-table__body__row__item--expanded"
>
<slot
:name="`expanded-row-${rowIndex}`"
:item="item"
:index="rowIndex"
>
<slot name="expanded-row" :item="item" :index="rowIndex">
{{ item }}
</slot>
</td>
<td
v-if="stickyLastCol"
:class="[
'puik-table__body__row__item puik-table__body__row__item--selection',
{ 'puik-table__body__row__item--sticky': stickyLastCol },
{
'puik-table__body__row__item--sticky-scroll':
stickyLastCol &&
ScrollBarPosition ==
PuikTableScrollBarPosistion.ISSCROLLING,
},
{
'puik-table__body__row__item--sticky-left':
stickyLastCol &&
ScrollBarPosition == PuikTableScrollBarPosistion.LEFT,
},
{
'puik-table__body__row__item--sticky-right':
stickyLastCol &&
ScrollBarPosition == PuikTableScrollBarPosistion.RIGHT,
},
]"
></td>
</tr>
</template>
</tbody>
Expand All @@ -206,7 +249,7 @@ import {
PuikTableSortIcon,
PuikTableScrollBarPosistion,
} from './table'
import type { ServerSortOption } from './table'
import type { sortOption } from './table'
defineOptions({
name: 'PuikTable',
})
Expand All @@ -217,8 +260,7 @@ const emit = defineEmits<{
(e: 'select', index: number): void
(e: 'select:all'): void
(e: 'update:selection', value: number[]): void
// (e: 'update:serverOptions', value: ServerOption): void
(e: 'sortColumn', column: ServerSortOption): void
(e: 'sortColumn', column: sortOption): void
}>()
const { t } = useLocale()
const checked = ref<number[]>(props.selection)
Expand All @@ -227,13 +269,15 @@ const ScrollBarPosition = ref<string>('left')
const lastScrollLeft = ref(0)
const sortOrder = ref([])
const sortIcon = ref({})
const sortedItems = ref([...props.items])
const data = ref([...props.items])
const currentSortCol = ref('')
const sortTable = (headerCol: string) => {
const resetSortIcons = () => {
for (const col in sortIcon.value) {
sortIcon.value[col] = PuikTableSortIcon.DEFAULT
}
}
const setSortOrderAndIcon = (headerCol: string) => {
if (sortOrder.value[headerCol]) {
sortOrder.value[headerCol] =
sortOrder.value[headerCol] === PuikTableSortOrder.ASC &&
Expand All @@ -248,25 +292,33 @@ const sortTable = (headerCol: string) => {
sortOrder.value[headerCol] = PuikTableSortOrder.ASC
sortIcon.value[headerCol] = PuikTableSortIcon.ASC
}
}
const sortDataLocally = (headerCol: string) => {
const order = sortOrder.value[headerCol] === PuikTableSortOrder.ASC ? 1 : -1
sortedItems.value.sort(
(a, b) => order * (a[headerCol] < b[headerCol] ? -1 : 1)
)
data.value.sort((a, b) => order * (a[headerCol] < b[headerCol] ? -1 : 1))
}
const sortTable = (headerCol: string) => {
if (!props.sortFromServer) {
sortDataLocally(headerCol)
}
resetSortIcons()
setSortOrderAndIcon(headerCol)
const options = {
sortBy: headerCol,
sortOrder: sortOrder.value[headerCol],
} as ServerSortOption
} as sortOption
emit('sortColumn', options)
currentSortCol.value = headerCol
return sortedItems.value
return data.value
}
const getScrollBarPosition = async (event: Event) => {
const target = event.target as HTMLElement
if (target.scrollLeft === 0) {
ScrollBarPosition.value = PuikTableScrollBarPosistion.LEFT
} else if (
Math.abs(target.scrollLeft + target.offsetWidth - target.scrollWidth) < 10
Math.abs(target.scrollLeft + target.offsetWidth - target.scrollWidth) < 20
) {
ScrollBarPosition.value = PuikTableScrollBarPosistion.RIGHT
} else {
Expand Down
12 changes: 10 additions & 2 deletions packages/components/table/stories/table.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default {
},
},
},
'`expanded-row-${rowIndex}`': {
'expanded-row': {
control: 'none',
description: 'slot for expanded row content',
table: {
Expand Down Expand Up @@ -186,7 +186,15 @@ export default {
description: 'Event emitted when sorting a column',
table: {
type: {
summary: 'string',
summary: 'sortOption',
detail: `
import type { sortOption } from '@prestashopcorp/puik/es/components/table/src/table'
type sortOption = {
sortBy?: string
sortOrder?: PuikTableSortOrder
}
`,
},
},
},
Expand Down
21 changes: 20 additions & 1 deletion packages/components/table/test/table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import { describe, it, expect } from 'vitest'
import { faker } from '@faker-js/faker'
import { locales } from '@puik/locale'
import PuikTable from '../src/table.vue'
import {
PuikTableSortOrder,
type PuikTableHeader,
type sortOption,
} from '../src/table'
import type { MountingOptions, VueWrapper } from '@vue/test-utils'
import type { PuikTableHeader } from '../src/table'

const defaultItems = Array(5)
.fill(null)
Expand Down Expand Up @@ -314,4 +318,19 @@ describe('Table tests', () => {
'puik-table__head__row__item--expandable'
)
})

it('should emit sortColum event', async () => {
const headers: PuikTableHeader[] = [{ value: 'firstname', sortable: true }]
factory({ headers })
const header = getHeaders()[0]
const SortButton = header.find('.puik-button')
const payload: sortOption = {
sortBy: 'firstname',
sortOrder: PuikTableSortOrder.ASC,
}
expect(SortButton.classes()).toContain('puik-button')
await SortButton.trigger('click')
expect(wrapper.emitted('sortColumn')).toBeTruthy()
expect(wrapper.emitted('sortColumn')?.[0]?.[0]).toStrictEqual(payload)
})
})
2 changes: 1 addition & 1 deletion packages/theme/src/table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
tr {
.puik-table__head__row__item--sticky,
.puik-table__body__row__item--sticky {
@apply sticky bg-white;
@apply sticky bg-white z-10;
}

.puik-table__head__row__item--sticky-scroll,
Expand Down

0 comments on commit 8952292

Please sign in to comment.