Skip to content

Commit a03f2a0

Browse files
authored
Update mixin-sorting.js
1 parent dd5b0a7 commit a03f2a0

File tree

1 file changed

+87
-109
lines changed

1 file changed

+87
-109
lines changed

src/components/table/helpers/mixin-sorting.js

Lines changed: 87 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -93,48 +93,23 @@ export default {
9393
},
9494
data() {
9595
return {
96-
localSortBy: [''],
97-
localSortDesc: [false]
96+
// Array of sort Objects: [{ sortBy: 'field', sortDesc: false }, ... ]
97+
// Will be an empty array if no sorting
98+
localSortInfo: []
9899
}
99100
},
100101
computed: {
101102
localSorting() {
102103
return this.hasProvider ? !!this.noProviderSorting : !this.noLocalSorting
103104
},
104105
isSortable() {
105-
return this.computedFields.some(f => f.sortable)
106+
return this.computedFields.some(field => field.sortable)
106107
},
107108
computedSortBy() {
108-
return this.sortMulti ? this.localSortBy : this.localSortBy.slice(0, 1)
109+
return this.localSortInfo.map(info => info.sortBy)
109110
},
110111
computedSortDesc() {
111-
// Ensure values are tri-state (true, false, null), and same length as localSortBy array
112-
const sortDesc = this.localSortBy.map(
113-
(_, idx) => (isBoolean(this.localSortDesc[idx]) ? this.localSortDesc[idx] : null)
114-
)
115-
return this.sortMulti ? sortDesc : sortDesc.slice(0, 1)
116-
},
117-
computedSortInfo() {
118-
// TODO in this PR:
119-
// Make sortInfo a data property which we update
120-
// via watchers on sortBy/SortDesc and event handlers.
121-
// When a column is no longer sorted (null) we remove it from the array
122-
const computedSortDesc = this.computedSortDesc
123-
const computedFieldsObj = this.computedFieldsObj
124-
return this.localSortBy
125-
.map((key, idx) => {
126-
const field = computedFieldsObj[key] || {}
127-
return {
128-
sortBy: key,
129-
sortDesc: computedSortDesc[idx],
130-
formatter: isFunction(field.formatter)
131-
? field.formatter
132-
: field.formatter
133-
? this.getFieldFormatter(key)
134-
: undefined
135-
}
136-
})
137-
.filter(x => x.sortBy && isBoolean(x.sortDesc))
112+
return this.localSortInfo.map(info => info.sortDesc)
138113
},
139114
sortedItems() {
140115
// Sorts the filtered items and returns a new array of the sorted items
@@ -190,47 +165,64 @@ export default {
190165
this.$off('head-clicked', this.handleSort)
191166
}
192167
},
193-
sortBy(newVal, oldVal) {
194-
if (looseEqual(newVal, this.localSortBy)) {
195-
/* istanbul ignore next */
196-
return
168+
sortBy(newVal) {
169+
// Update localSortInfo object
170+
if (!looseEqual(newVal, this.computedSortBy)) {
171+
// Update localSortInfo object
172+
this.updateLocalSortInfo(newVal, this.sortDesc)
197173
}
198-
// TODO in this PR:
199-
// Update sortInfo object
200-
this.localSortBy = newVal ? concat(newVal) : []
201174
},
202-
sortDesc(newVal, oldVal) {
203-
if (looseEqual(newVal, this.localSortDesc)) {
204-
/* istanbul ignore next */
205-
return
175+
sortDesc(newVal) {
176+
// Update localSortInfo object
177+
if (!looseEqual(newVal, this.computedSortDesc)) {
178+
this.updateLocalSortInfo(this.sortBy, newVal)
206179
}
207-
// TODO in this PR:
208-
// Update sortInfo object
209-
newVal = isUndefined(newVal) ? [] : concat(newVal)
210-
this.localSortDesc = newVal.map(d => (isBoolean(d) ? d : null))
211180
},
212181
// Update .sync props
213-
// TODO in this PR:
214-
// Instead watch the sortInfo array, and emit the apropriate
215-
// updated values as needed
216-
localSortDesc(newVal, oldVal) {
217-
// Emit update to sort-desc.sync
218-
if (!looseEqual(newVal, oldVal)) {
219-
this.$emit('update:sortDesc', this.sortMulti ? newVal : newVal[0])
182+
computedSortBy(newSortBy = [], oldSortBy = []) {
183+
if (!looseEqual(newSortBy, oldSortBy)) {
184+
// Emit update to sort-by.sync
185+
this.$emit('update:sortBy', this.sortMulti ? newSortBy : newSortBy[0] || '')
220186
}
221187
},
222-
localSortBy(newVal, oldVal) {
223-
if (!looseEqual(newVal, oldVal)) {
224-
this.$emit('update:sortBy', this.sortMulti ? newVal : newVal[0])
188+
computedSortDesc(newSortDesc = [], oldSortDesc = []) {
189+
if (!looseEqual(newSortDesc, oldSortDesc)) {
190+
// Emit update to sort-desc.sync
191+
this.$emit('update:sortBy', this.sortMulti ? newSortDesc : newSortDesc[0] || '')
225192
}
226193
}
227194
},
228195
created() {
229196
if (this.isSortable) {
230197
this.$on('head-clicked', this.handleSort)
198+
// Update sortInfo object
199+
this.updateLocalSortInfo(this.sortBy, newVal)
231200
}
232201
},
233202
methods: {
203+
updateLocalSortInfo(sortBy, sortDesc) {
204+
if (this.isSortable) {
205+
// Updates localSortInfo array with the given values
206+
const sortByArr = concat(sortBy).filter(s => !isUndefinedOrNull(s))
207+
const sortDescArr = concat(sortDesc)
208+
const computedFieldsObj = this.computedFieldsObj
209+
this.localSortInfo = sortByArr.map((key, idx) => {
210+
const field = computedFieldsObj[key] || {}
211+
return {
212+
sortBy: String(key),
213+
sortDesc: Boolean(sortDescArr[idx]),
214+
formatter: isFunction(field.formatter)
215+
? field.formatter
216+
: field.formatter
217+
? this.getFieldFormatter(key)
218+
: undefined
219+
}
220+
})
221+
} else {
222+
// Not sortable so reset the localSortInfo array
223+
this.localSortInfo = []
224+
}
225+
},
234226
// Handlers
235227
handleSort(key, field, evt, isFoot) {
236228
if (!this.isSortable) {
@@ -246,53 +238,45 @@ export default {
246238
// const sequence = this.sortDirection === 'desc' ? [true, false, null] : [false, true, null]
247239
// TODO in this PR:
248240
// Handle this via lookup
249-
const sortBy = this.localSortBy[0]
250-
// TODO: make this tri-state sorting (for multi-sort only)
251-
// cycle desc => asc => none => desc => ...
241+
const sortMulti = this.sortMulti
242+
const sortInfo = this.localSortInfo
243+
const sortIndex = this.computedSortBy.indexOf(key)
252244
let sortChanged = false
253-
const toggleLocalSortDesc = () => {
254-
const sortDirection = field.sortDirection || this.sortDirection
255-
if (sortDirection === 'asc') {
256-
this.localSortDesc = [false]
257-
} else if (sortDirection === 'desc') {
258-
this.localSortDesc = [true]
259-
} else {
260-
// sortDirection === 'last'
261-
// Leave at last sort direction from previous column
262-
// TODO in this PR:
263-
// If multi-sort, then use sort sequence
264-
}
265-
}
245+
// Get the initial sort Direction
246+
const intialDirection = sortMulti
247+
? this.sortDirection
248+
: field.sortDirection || this.sortDirection
249+
const intialSortDesc = intialDirection === 'asc'
250+
? false
251+
: intialDirection === 'desc'
252+
? true
253+
: sortMulti
254+
? false
255+
: (sortInfo[0] || {}).sortDesc || false
266256
if (field.sortable) {
267-
// TODO in this PR:
268-
// handle toggling on the index
269-
if (key === sortBy) {
270-
// Change sorting direction on current column
271-
// this.localSortDesc[0] = !this.localSortDesc[0]
272-
this.localSortDesc = [!this.localSortDesc[0]]
273-
// TODO in this PR:
274-
// Check if sort is clearing (third click), and
275-
// if so remove the sort item from both localSortBy/localSortDesc
257+
if (sortIndex === -1) {
258+
// Field not sorted currently
259+
this.localSortInfo.push({
260+
sortBy: key,
261+
sortDesc: intialSortDesc
262+
})
276263
} else {
277-
// Start sorting this column ascending
278-
this.localSortBy[0] = key
279-
// this.localSortDesc = false
280-
toggleLocalSortDesc()
264+
// Field is currently sorted
265+
if (sortInfo[sortIndex].sortDesc === intialSortDesc) {
266+
// If transitioning from true<=>false, toggle the direction
267+
sortInfo[sortIndex].sortDesc = !sortInfo[sortIndex].sortDesc
268+
} else {
269+
// Else transitoning to unsorted, so remove from sort info
270+
this.localSortInfo.splice(sortIndex, 1)
271+
}
281272
}
282273
sortChanged = true
283274
} else if (this.computedSortInfo.length > 0 && !this.noSortReset) {
284-
this.localSortBy = []
285-
if (this.sortMulti) {
286-
this.localSortDesc = []
287-
} else {
288-
toggleLocalSortDesc()
289-
}
275+
this.localSortInfo = []
290276
sortChanged = true
291-
// } else {
292-
// sortChanged = false
293277
}
294278
if (sortChanged) {
295-
// Sorting parameters changed
279+
// Sorting parameters changed via user interaction
296280
this.$emit('sort-changed', this.context)
297281
}
298282
},
@@ -310,18 +294,10 @@ export default {
310294
return {}
311295
}
312296
const sortable = field.sortable
313-
// TODO in this PR:
314-
// This is just temporary. Will need to lookup the index of this
315-
// key in this.localSortBy or this.localSortInfo
316-
const sortOrder = 1
317-
// TODO for this PR:
318-
// Find index of key in this.computedSortBy (or this.computedSortInfo),
319-
// and then grab the sorting value
320-
const sortDesc = this.localSortDesc[0]
321-
// TODO in this PR:
322-
// This is just temporary. Will need to lookup if this column key is
323-
// in this.localSortBy
324-
const sortBy = this.localSortBy[0]
297+
const sortIndex = this.computedSortBy.indexOf(key)
298+
const sortOrder = sortIndex + 1
299+
const sortBy = this.computedSortBy[sortIndex]
300+
const sortDesc = this.computedSortDesc[sortIndex] || false
325301
// Now we get down to business determining the aria-label value
326302
let ariaLabel = ''
327303
if ((!field.label || !field.label.trim()) && !field.headerTitle) {
@@ -345,7 +321,9 @@ export default {
345321
// Default for ariaLabel
346322
ariaLabelSorting = sortDesc ? this.labelSortDesc : this.labelSortAsc
347323
// Handle sortDirection setting
348-
const sortDirection = this.sortDirection || field.sortDirection
324+
const sortDirection = this.sortMulti
325+
? this.sortDirection
326+
: this.sortDirection || field.sortDirection
349327
if (sortDirection === 'asc') {
350328
ariaLabelSorting = this.labelSortAsc
351329
} else if (sortDirection === 'desc') {
@@ -354,7 +332,7 @@ export default {
354332
}
355333
} else if (!this.noSortReset) {
356334
// Non sortable column
357-
ariaLabelSorting = this.localSortBy ? this.labelSortClear : ''
335+
ariaLabelSorting = sortInfo.length > 0 ? this.labelSortClear : ''
358336
}
359337
// Assemble the aria-label attribute value
360338
ariaLabel = [ariaLabel.trim(), ariaLabelSorting.trim()].filter(Boolean).join(': ')
@@ -380,7 +358,7 @@ export default {
380358
// And figure out how to set a variant for this badge
381359
// May require additiona CSS generation. or we just make 2 options: dark and light
382360
// Or use the column text variant (currentColor) to make an outline badge
383-
'data-sort-order': this.sortMulti ? String(sortOrder) : null
361+
'data-sort-order': this.sortMulti && sortOrder ? String(sortOrder) : null
384362
}
385363
}
386364
}

0 commit comments

Comments
 (0)