@@ -15,16 +15,17 @@ import { CommonModule, Location } from "@angular/common";
1515import { MatSidenavModule } from "@angular/material/sidenav" ;
1616import { MatIconModule } from "@angular/material/icon" ;
1717
18+ interface NavigationEntryTag {
19+ type : string ;
20+ value : string ;
21+ }
1822interface NavigationEntry {
1923 name : string [ ] ;
2024 icon ?: string ;
2125 href : string | undefined ;
2226 selected ?: boolean ;
2327 collapsed ?: boolean ;
24- tags ?: {
25- type : string ;
26- value : string ;
27- } [ ] ;
28+ tags ?: NavigationEntryTag [ ] ;
2829 children ?: NavigationEntry [ ] ;
2930}
3031
@@ -102,7 +103,7 @@ export class SidenavComponent implements OnInit, AfterViewInit {
102103 const channel = {
103104 name : this . splitForWordBreaking ( value . name ) ,
104105 href : AsyncApiMapperService . BASE_URL + value . anchorIdentifier ,
105- tags : Array . from ( new Set ( tags ) ) . sort ( ) ,
106+ tags : this . filterAndSort ( tags , "value" ) ,
106107 children : children ,
107108 } ;
108109
@@ -135,6 +136,20 @@ export class SidenavComponent implements OnInit, AfterViewInit {
135136 return text . split ( / (?< = [ . , _ / \- ] ) / ) ;
136137 } ;
137138
139+ private filterAndSort < A > ( arr : A [ ] , key : keyof A ) : A [ ] {
140+ const seen = new Set < string > ( ) ;
141+ const uniqueArr = arr . filter ( ( item ) => {
142+ const serializedItem = JSON . stringify ( item ) ;
143+ return seen . has ( serializedItem ) ? false : seen . add ( serializedItem ) ;
144+ } ) ;
145+
146+ return uniqueArr . sort ( ( a , b ) => {
147+ if ( a [ key ] < b [ key ] ) return - 1 ;
148+ if ( a [ key ] > b [ key ] ) return 1 ;
149+ return 0 ;
150+ } ) ;
151+ }
152+
138153 ngAfterViewInit ( ) {
139154 this . scrollableElement . nativeElement . addEventListener (
140155 "scroll" ,
0 commit comments