Skip to content

Commit ab0e616

Browse files
committed
Customizable sort parameters per field
Co-author: @erikap
1 parent 9f553d7 commit ab0e616

7 files changed

Lines changed: 75 additions & 59 deletions

File tree

addon/components/data-table.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
enableSelection=this.enableSelection
1313
enableLineNumbers=@enableLineNumbers
1414
onClickRow=@onClickRow
15+
sort=@sort
1516
updateSort=this.updateSort
1617
customHeaders=this.customHeaders
1718
fields=this.fields

addon/components/data-table.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,33 @@ export default class DataTable extends Component {
115115
}
116116
}
117117

118+
attributeToSortParams(attribute) {
119+
if( this.args.attributeToSortParams ) {
120+
return this.args.attributeToSortParams(attribute);
121+
} else {
122+
const attr = attribute.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
123+
return { asc: attr, desc: `-${attr}` };
124+
}
125+
}
126+
118127
get fields() {
119128
return this
120129
.fieldsWithMeta
121-
.map( ({ attribute, label, isSortable, hasCustomHeader, isCustom }) => ({
130+
.map( ({ attribute, label, isSortable, hasCustomHeader, isCustom, sortParameters }) => ({
122131
attribute,
123132
label,
124-
isSortable: isSortable
125-
|| !this.sortableFields
126-
|| this.sortableFields.includes(attribute),
133+
// custom format says it's sortable: sort params known
134+
// say it should be sortable: use attribute to sort param
135+
// field included in sortable fields: use attribute to sort param
136+
sortParameters: sortParameters
137+
|| ( ( isSortable || this.sortableFields.includes(attribute) )
138+
&& this.attributeToSortParams(attribute) ),
139+
get isSortable() { return Object.keys( this.sortParameters || {} ).length > 1; },
127140
hasCustomHeader: hasCustomHeader
128141
|| this.customHeaders.includes(attribute),
129142
isCustom: isCustom
130143
|| this.customFields.includes(attribute)
131-
}) );
144+
}));
132145
}
133146

134147
get customHeaders() {

addon/components/data-table/data-table-content-header.hbs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22
{{yield (hash
33
enableSelection=@enableSelection
44
enableLineNumbers=@enableLineNumbers
5-
fields=@fields
6-
currentSorting=@dataTable.sort
5+
sort=@sort
76
updateSort=@updateSort
8-
customHeaders=@customHeaders
97
hasLinks=@hasLinks
8+
customHeaders=@customHeaders
9+
fields=@fields
1010
dataHeadersInfo=(hash
1111
fields=@fields
12-
currentSorting=@dataTable.sort
1312
customHeaders=@customHeaders
13+
sort=@sort
1414
updateSort=@updateSort)
1515
ThSortable=(component
1616
"data-table/th-sortable"
1717
fields=@fields
18-
currentSorting=@dataTable.sort
19-
customHeaders=@customHeaders
18+
sort=@sort
2019
updateSort=@updateSort))}}

addon/components/data-table/data-table-content.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Header=(component "data-table/data-table-content-header"
55
enableSelection=@enableSelection
66
enableLineNumbers=@enableLineNumbers
7+
sort=@sort
78
updateSort=@updateSort
89
hasLinks=this.hasLinks
910
customHeaders=@customHeaders
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
{{!-- Used in: data-table/data-table-content-header --}}
22
{{yield (hash
3-
isSorted=this.isSorted
4-
inverseSorting=this.inverseSorting
5-
isSortable=@field.isSortable
63
label=@field.label
74
attribute=@field.attribute
8-
order=this.order
5+
6+
isSortable=@field.isSortable
7+
isSorted=this.isSorted
8+
toggleSort=this.toggleSort
9+
nextSort=this.nextSort
10+
11+
isAscending=this.isAscending
12+
isDescending=this.isDescending
13+
sortDirection=this.sortDirection
14+
915
renderCustomBlock=this.renderCustomBlock
1016
isCustom=this.isCustom
1117
hasCustom=this.hasCustom)}}

addon/components/data-table/th-sortable.js

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,28 @@ import { action } from '@ember/object';
22
import Component from '@glimmer/component';
33

44
export default class ThSortableComponent extends Component {
5-
// TODO: this is a json-api translation and it should be configurable on the data-table
6-
get dasherizedField() {
7-
return this.args.field.attribute.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
5+
get sortParameters() {
6+
return this.args.field.sortParameters;
87
}
98

10-
/**
11-
Inverses the sorting parameter
12-
E.g. inverseSorting('title') returns '-title'
13-
inverseSorting('-title') returns 'title'
14-
*/
15-
_inverseSorting(sorting) {
16-
if (sorting.substring(0, 1) === '-') {
17-
return sorting.substring(1);
18-
} else {
19-
return '-' + sorting;
20-
}
9+
get sortDirection() {
10+
for ( const key in this.sortParameters )
11+
if( this.args.sort == this.sortParameters[key] )
12+
return key;
13+
14+
return '';
2115
}
2216

23-
get isSorted() {
24-
return (
25-
this.args.currentSorting === this.dasherizedField ||
26-
this.args.currentSorting === this._inverseSorting(this.dasherizedField)
27-
);
17+
get isAscending() {
18+
return this.sortDirection === "asc";
19+
}
20+
21+
get isDescending() {
22+
return this.sortDirection === "desc";
2823
}
2924

30-
get order() {
31-
if (this.args.currentSorting === this.dasherizedField) {
32-
return 'asc';
33-
} else if (this.args.currentSorting === `-${this.dasherizedField}`) {
34-
return 'desc';
35-
} else {
36-
return '';
37-
}
25+
get isSorted() {
26+
return this.sortDirection !== '';
3827
}
3928

4029
get renderCustomBlock() {
@@ -55,22 +44,27 @@ export default class ThSortableComponent extends Component {
5544
return this.args.fields.find(({hasCustomHeader}) => hasCustomHeader) || false;
5645
}
5746

47+
get availableSortOptions() {
48+
const options = [];
49+
Object
50+
.keys( this.sortParameters )
51+
.sort() // for asc and desc, asc first then desc, the rest also sorted for now
52+
.map( (key) => options.push(key) );
53+
options.push(''); // no sorting
54+
return options;
55+
}
56+
57+
get nextSort() {
58+
// wrapping loop over availableSortOptions
59+
const opts = this.availableSortOptions;
60+
return opts[(opts.indexOf(this.sortDirection) + 1) % opts.length];
61+
}
62+
5863
/**
59-
Sets the current sorting parameter.
60-
Note: the current sorting parameter may contain another field than the given field.
61-
In case the given field is currently sorted ascending, change to descending.
62-
In case the given field is currently sorted descending, clean the sorting.
63-
Else, set the sorting to ascending on the given field.
64-
*/
64+
* Wraps around possible sorting directions.
65+
*/
6566
@action
66-
inverseSorting() {
67-
if (this.order === 'asc') {
68-
this.args.updateSort(this._inverseSorting(this.args.currentSorting));
69-
} else if (this.order === 'desc') {
70-
this.args.updateSort('');
71-
} else {
72-
// if currentSorting is not set to this field
73-
this.args.updateSort(this.dasherizedField);
74-
}
67+
toggleSort() {
68+
this.args.updateSort(this.sortParameters[this.nextSort]);
7569
}
7670
}

addon/components/raw-data-table.hbs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
@rowLink={{@rowLink}}
2222
@customHeaders={{@customHeaders}}
2323
@customFields={{@customFields}}
24+
@sortableFields={{@sortableFields}}
25+
@attributeToSortParams={{@attributeToSortParams}}
2426
as |dt|>
2527
{{!-- START: search --}}
2628
<div class="raw-data-table">
@@ -119,8 +121,8 @@
119121
{{else}}
120122
{{#if dataHeader.isSortable}}
121123
<th class={{concat "sortable" (if dataHeader.isSorted " sorted" "")}}>
122-
<span role="button" {{on "click" dataHeader.inverseSorting}}>
123-
{{#if dataHeader.order}}[{{dataHeader.order}}]{{/if}}
124+
<span role="button" {{on "click" dataHeader.toggleSort}}>
125+
{{#if dataHeader.isSorted}}[{{dataHeader.sortDirection}}]{{/if}}
124126
{{dataHeader.label}}
125127
</span>
126128
</th>

0 commit comments

Comments
 (0)