@@ -787,49 +787,47 @@ function renderAttributesList(md: MarkdownIt, locale?: LocaleConfig): string {
787787
788788 if ( entries . length === 0 ) return ''
789789
790- // Group by pagePath
791- const groups = new Map < string , RegistryEntry [ ] > ( )
792- for ( const entry of entries ) {
793- const list = groups . get ( entry . pagePath ) || [ ]
794- list . push ( entry )
795- groups . set ( entry . pagePath , list )
796- }
797-
798- const tableLabels : Record < string , { attr : string ; desc : string } > = {
799- en : { attr : 'Attribute' , desc : 'Description' } ,
800- ru : { attr : 'Атрибут' , desc : 'Описание' } ,
790+ const tableLabels : Record < string , { attr : string ; plugin : string ; desc : string } > = {
791+ en : { attr : 'Attribute' , plugin : 'Plugin' , desc : 'Description' } ,
792+ ru : { attr : 'Атрибут' , plugin : 'Плагин' , desc : 'Описание' } ,
801793 }
802794 const l = tableLabels [ localeCode ] ?? tableLabels . en
803795
804- // Sort groups by plugin name
805- const sortedGroups = [ ...groups . entries ( ) ] . sort ( ( a , b ) => {
806- const nameA = getPluginByPagePath ( localeCode , a [ 0 ] ) ?. name ?? a [ 0 ]
807- const nameB = getPluginByPagePath ( localeCode , b [ 0 ] ) ?. name ?? b [ 0 ]
808- return nameA . localeCompare ( nameB )
809- } )
810-
811- let html = ''
812-
813- for ( const [ pagePath , attrs ] of sortedGroups ) {
814- const plugin = getPluginByPagePath ( localeCode , pagePath )
815- const groupName = plugin ?. name ?? pagePath . split ( '/' ) . pop ( ) ?? 'Unknown'
816- const slug = 'attrs-' + groupName . toLowerCase ( ) . replace ( / \s + / g, '-' )
817-
818- if ( plugin ) {
819- const pluginHtml = renderPluginRefHtml ( plugin . name , locale )
820- html += `<h2 id="${ escapeHtml ( slug ) } ">${ pluginHtml } </h2>\n`
821- } else {
822- html += `<h2 id="${ escapeHtml ( slug ) } ">${ escapeHtml ( groupName ) } </h2>\n`
823- }
824-
825- html += `<table>\n<thead><tr><th>${ escapeHtml ( l . attr ) } </th><th>${ escapeHtml ( l . desc ) } </th></tr></thead>\n<tbody>\n`
826- for ( const attr of attrs ) {
827- const attrHtml = renderAttrRefHtml ( md , attr . fqn , locale )
828- const shortHtml = attr . short ? md . renderInline ( attr . short ) : ''
829- html += `<tr><td>${ attrHtml } </td><td>${ shortHtml } </td></tr>\n`
830- }
831- html += '</tbody>\n</table>\n'
832- }
796+ // Build flat rows
797+ const rows : { name : string ; plugin : string ; attrHtml : string ; pluginHtml : string ; shortHtml : string } [ ] = [ ]
833798
799+ for ( const entry of entries ) {
800+ const plugin = getPluginByPagePath ( localeCode , entry . pagePath )
801+ const pluginName = plugin ?. name ?? entry . pagePath . split ( '/' ) . pop ( ) ?? ''
802+ const shortName = stripNamespaceShort ( entry . fqn )
803+
804+ rows . push ( {
805+ name : shortName ,
806+ plugin : pluginName ,
807+ attrHtml : renderAttrRefHtml ( md , entry . fqn , locale ) ,
808+ pluginHtml : plugin ? renderPluginRefHtml ( plugin . name , locale ) : escapeHtml ( pluginName ) ,
809+ shortHtml : entry . short ? md . renderInline ( entry . short ) : '' ,
810+ } )
811+ }
812+
813+ // Default sort by name
814+ rows . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
815+
816+ let html = '<table class="attr-sortable">\n'
817+ html += '<thead><tr>'
818+ html += `<th data-sort="name" data-dir="asc">${ escapeHtml ( l . attr ) } </th>`
819+ html += `<th data-sort="plugin">${ escapeHtml ( l . plugin ) } </th>`
820+ html += `<th>${ escapeHtml ( l . desc ) } </th>`
821+ html += '</tr></thead>\n<tbody>\n'
822+
823+ for ( const row of rows ) {
824+ html += `<tr data-name="${ escapeHtml ( row . name . toLowerCase ( ) ) } " data-plugin="${ escapeHtml ( row . plugin . toLowerCase ( ) ) } ">`
825+ html += `<td>${ row . attrHtml } </td>`
826+ html += `<td>${ row . pluginHtml } </td>`
827+ html += `<td>${ row . shortHtml } </td>`
828+ html += '</tr>\n'
829+ }
830+
831+ html += '</tbody>\n</table>\n'
834832 return html
835833}
0 commit comments