@@ -15,6 +15,7 @@ class TableLinked {
1515
1616 this . updateContent ( ) ;
1717 this . updateSelectionText ( DataUtils . getTechsFromURL ( ) ) ;
18+ this . initSortHeaders ( ) ;
1819
1920 const rowCount = document . getElementById ( 'rowsPerPage' ) ;
2021 rowCount ?. addEventListener ( 'change' , ( e ) => this . updateRowsPerPage ( e ) ) ;
@@ -61,9 +62,16 @@ class TableLinked {
6162 const sortEndpoint = component . dataset . sortEndpoint ;
6263 const sortMetric = component . dataset . sortMetric ;
6364 const sortKey = component . dataset . sortKey ;
65+ const sortOrder = component . dataset . sortOrder || 'desc' ;
6466 const client = component . dataset . client ;
6567
66- if ( sortMetric ) {
68+ if ( sortMetric === 'technology' ) {
69+ this . dataArray = this . dataArray . sort ( ( techA , techB ) => {
70+ const aName = techA [ 0 ] ?. technology || '' ;
71+ const bName = techB [ 0 ] ?. technology || '' ;
72+ return sortOrder === 'asc' ? aName . localeCompare ( bName ) : bName . localeCompare ( aName ) ;
73+ } ) ;
74+ } else if ( sortMetric ) {
6775 this . dataArray = this . dataArray . sort ( ( techA , techB ) => {
6876 // Sort techs by date to get the latest
6977 const aSortedDate = techA . sort ( ( a , b ) => new Date ( b . date ) - new Date ( a . date ) ) ;
@@ -78,6 +86,9 @@ class TableLinked {
7886 const aValue = aMetric ?. [ client ] ?. [ sortKey ] ;
7987 const bValue = bMetric ?. [ client ] ?. [ sortKey ] ;
8088
89+ if ( sortOrder === 'asc' ) {
90+ return aValue - bValue > 0 ? 1 : - 1 ;
91+ }
8192 return bValue - aValue > 0 ? 1 : - 1 ;
8293 } ) ;
8394 }
@@ -326,6 +337,91 @@ class TableLinked {
326337 const rowsAnnouncement = document . getElementById ( 'rows-announcement' ) ;
327338 rowsAnnouncement . innerText = `Showing ${ this . rows } rows.` ;
328339 }
340+
341+ initSortHeaders ( ) {
342+ const component = document . getElementById ( `table-${ this . id } ` ) ;
343+ const headers = component . querySelectorAll ( 'thead th' ) ;
344+
345+ headers . forEach ( th => {
346+ const endpoint = th . dataset . endpoint ;
347+ const metric = th . dataset . metric ;
348+ const key = th . dataset . key ;
349+
350+ const isSortable = ( key === 'technology' ) || ( endpoint && metric ) ;
351+ if ( ! isSortable ) return ;
352+
353+ const btn = document . createElement ( 'button' ) ;
354+ btn . className = 'sort-btn' ;
355+ btn . setAttribute ( 'type' , 'button' ) ;
356+ while ( th . firstChild ) {
357+ btn . appendChild ( th . firstChild ) ;
358+ }
359+ th . appendChild ( btn ) ;
360+ btn . addEventListener ( 'click' , ( ) => this . onSortClick ( th ) ) ;
361+ } ) ;
362+
363+ this . updateSortIndicators ( ) ;
364+ }
365+
366+ onSortClick ( th ) {
367+ const component = document . getElementById ( `table-${ this . id } ` ) ;
368+ const endpoint = th . dataset . endpoint || '' ;
369+ const subcategory = th . dataset . subcategory || '' ;
370+ const metric = th . dataset . metric || '' ;
371+ const key = th . dataset . key ;
372+
373+ const isTechColumn = key === 'technology' ;
374+ const currentOrder = component . dataset . sortOrder || 'desc' ;
375+
376+ const isCurrentCol = isTechColumn
377+ ? component . dataset . sortMetric === 'technology'
378+ : ( component . dataset . sortEndpoint === endpoint &&
379+ component . dataset . sortMetric === subcategory &&
380+ component . dataset . sortKey === metric ) ;
381+
382+ const newOrder = isCurrentCol && currentOrder === 'desc' ? 'asc' : 'desc' ;
383+
384+ if ( isTechColumn ) {
385+ component . dataset . sortEndpoint = '' ;
386+ component . dataset . sortMetric = 'technology' ;
387+ component . dataset . sortKey = 'technology' ;
388+ } else {
389+ component . dataset . sortEndpoint = endpoint ;
390+ component . dataset . sortMetric = subcategory ;
391+ component . dataset . sortKey = metric ;
392+ }
393+ component . dataset . sortOrder = newOrder ;
394+
395+ this . updateContent ( ) ;
396+ this . updateSortIndicators ( ) ;
397+ }
398+
399+ updateSortIndicators ( ) {
400+ const component = document . getElementById ( `table-${ this . id } ` ) ;
401+ const headers = component . querySelectorAll ( 'thead th' ) ;
402+ const sortMetric = component . dataset . sortMetric ;
403+ const sortEndpoint = component . dataset . sortEndpoint || '' ;
404+ const sortKey = component . dataset . sortKey || '' ;
405+ const sortOrder = component . dataset . sortOrder || 'desc' ;
406+
407+ headers . forEach ( th => {
408+ const endpoint = th . dataset . endpoint || '' ;
409+ const subcategory = th . dataset . subcategory || '' ;
410+ const metric = th . dataset . metric || '' ;
411+ const key = th . dataset . key ;
412+
413+ const isTechColumn = key === 'technology' ;
414+ const isActive = isTechColumn
415+ ? sortMetric === 'technology'
416+ : ( endpoint && endpoint === sortEndpoint && subcategory === sortMetric && metric === sortKey ) ;
417+
418+ if ( isActive ) {
419+ th . setAttribute ( 'aria-sort' , sortOrder === 'asc' ? 'ascending' : 'descending' ) ;
420+ } else {
421+ th . removeAttribute ( 'aria-sort' ) ;
422+ }
423+ } ) ;
424+ }
329425}
330426
331427export default TableLinked ;
0 commit comments