ta-good-table
TA Good Table is forked from Vue Good Table. We've made some updates to it to fit our Traction needs, and have been trying to capture the major changes below.
Installation
- Set up Satisfaction locally
- Install package:
npm install @technologyadvice/ta-good-table
import Component:
import VueGoodTable from '@technologyadvice/ta-good-table'
import Styles:
@import '~ta-good-table/src/styles/style.scss';
Local development
- Clone the repository / pull latest:
rr repo pull -fib ta-good-table
- Link the package to one or more applications:
rr app package link ta-good-table accounts-portal -b
Publish NPM package
Publishing of NPM packages to the Satisfaction registry happens automatically via the publish GitHub Actions workflow.
Filtering
To enable filtering on a column, pass a filterOptions property on the column object with the enabled flag. This will take all column field values and format it into an options dropdown.
filterOptions: {
enabled: true,
},
Initial filtering
You can set an initial filter value by passing in an object to VueGoodTable. When setting the filter options, ta-good-table will set the field's active property to true.
:initialFilter="{
field: plan_name, // name of the column field
value: Free, // value to filter by
}"
Multicolumn filters
Use this option if you have multiple columns that may share values and want only one filter dropdown to filter on both columns. Enable the filterOptions on both columns as shown above, and pass the following as a prop. For each set, the first field in the array will have the filter icon/dropdown.
:multi-column-filter="{
enabled: true,
columnSets: [
[ 'field_one', 'field_two' ],
],
}"
Static filters
Use this if you have a static list of filter options.
filterOptions: {
enabled: true,
type: 'remote',
staticFilterOptions: [
{ id: 1, value: 'testing' },
{ id: 2, value: 'testing123' },
],
promoteActiveOptions: true,
outputFilterIdentifier: 'test_options_selected',
},
Multifield columns
Use this option if you have multiple fields in a single column. You will need to add a subFields property to the column object:
subFields: [ {
field: 'cool-field',
label: 'Cool Field',
filterActive: false,
filterFn: method,
type: 'date'
} ],
To enable the filter, just pass the field name into the enableSubFields array (you also need the filterActive property shown above):
filterOptions: {
enableSubFields: [ 'client' ]
},
Sorting
Sorting is enabled by default. To disable, add sortable: false to the column object. Be sure to pass to pass the correct type for proper sorting.
:sort-options="{
enabled: true,
initialSortBy: {
field: 'field_name',
type: 'asc', // or 'desc'
}
}"
Types
Used for sorting (and possibly filtering in the future):
- boolean
- date
- decimal
- number
- percentage
Pagination is enabled by default and has the following options. Note: currently the TA pagination is only setup for position: bottom
:pagination-options="{
enabled: true,
perPage: 10,
position: 'bottom',
setCurrentPage: 1,
}"
Remote filtering is also possible - check out this confluence document for more information.
Clickable rows
For clickable rows, you may either listen for the on-row-click event (which will have the row in the payload), or you can use the clickable-row-options property for routing. rowProperty is the value the route will use in the query params.
:clickable-row-options="{
url: '/',
rowProperty: 'uuid',
useVueRouter: true,
}"
Class name
pass the class-name prop to the VueGoodTable to dynamically generate classes on the table, rows, and headers using the field property on the column object.
class-name: "cool-table" will generate:
- class
cool-table on the table root element
- class
cool-table__cool-field on the header and cells (if the field is cool-field)
- class
cool-table__cool-field--header on the column's header element
- class
cool-table__cool-field--cell on the column's cell element
- when two field names are the same, a tdClass can be passed in to differentiate the columns
- it will still follow the format of the other class names
cool-table__customname-cell
Zero state message
Pass the zero-state-message prop to the VueGoodTable if you want a custom zero state for that implementation of the table. The default message is "No results found" but good UX practices dictate selecting a zero message that is relevant to the content of your table.
- full-row: use
v-slot:table-full-row="props"
- row: use
v-slot:table-row="props"
- column: use
v-slot:table-column="props"
(see implementation below)
When mode="remote" and you have selectOptions.selectAllByPage=false, ta-good-tables uses prop selectedRowsRemote for its selected rows, selectOptions.selectionIdentifier for the row identifier to use when selecting, selectOptions.getAllSelectionItems function to get all selected rows and on-selected-rows-changed to keep the selectedRowsRemote updated.
selectOptions.selectionIdentifier is the unique field for a row, most likely uuid.
selectedRowsRemote is a prop for ta-good-tables that should be a list of your selectOptions.selectionIdentifier for each selected row.
selectOptions.getAllSelectionItems should return a list of all selectable row identifiers. This should take into account the same filtering and searching that the table is using. So if your current table only shows 3 rows and your selectOptions.selectionIdentifier is "uuid" then this function should return a list of the 3 UUIDs.
on-selected-rows-changed returns the current list of selected rows and should replace your selectedRowsRemote prop value.
Example implementation
Table:
<VueGoodTable
:cols="columns"
:rows="rows"
class-name="cool-table"
:clickable-row-options="{
url: '/cool',
rowProperty: 'uuid',
useVueRouter: true,
}"
:sort-options="{
enabled: true,
initialSortBy: {
field: 'date',
type: 'asc'/'desc',
}
}"
:multi-column-filter="{
enabled: true,
columnSets: [
[ 'field_one', 'field_two' ],
],
}"
:pagination-options="{
enabled: true,
mode: 'records',
perPage: type === 'unresolved' ? 10 : 5,
position: 'bottom',
}"
zero-state-message="Looks like you don't have any rows">
<template v-slot:table-full-row="props">
// use a custom component for the full row instead of just a single column
<td :colspan="columns.length">
<CustomRowComponent :item="props.row"></CustomRowComponent>
</td>
</template>
<template v-slot:table-row="props">
<span v-if="props.column.field == 'field_name'">
// Custom Row
</span>
</template>
<template v-slot:table-column="props">
<span v-if="props.column.field == 'field_name'">
// Custom Header
</span>
</template>
</VueGoodTable>
Columns
const columns = [
{
label: 'Name',
field: 'name',
subFields: [ { field: 'client', label: 'Client', filterActive: false } ],
filterOptions: {
enableSubField: [ 'client' ]
},
},
{
label: 'Brand',
field: 'brand',
filterOptions: {
enabled: true,
},
},
{
label: 'Date',
field: 'date',
type: 'date',
dateInputFormat: 'yyyy-MM-dd',
dateOutputFormat: 'E, MMM dd y',
},
{
label: 'Count',
field: 'count',
type: 'number',
},
]
Troubleshooting
Columns are blank
A common issue with blank columns happens when there are custom columns on the page
you may see something like this in the table-row slot:
<template v-if="props.column.field === 'name'">...</template>
<template v-if="props.column.field === 'date'">...</template>
The above code could cause blank columns. The solution would be every conditional <template> after the initial v-if, should be a v-else-if
<span v-if="props.column.field === 'name'"></span>
<span v-else-if="props.column.field === 'date'"></span>