shamrickus commented on code in PR #7303:
URL: https://github.com/apache/trafficcontrol/pull/7303#discussion_r1086071676


##########
experimental/traffic-portal/src/app/shared/navigation/tp-sidebar/tp-sidebar.component.ts:
##########
@@ -0,0 +1,140 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NestedTreeControl } from "@angular/cdk/tree";
+import { Component, OnInit, ViewChild } from "@angular/core";
+import { MatSidenav } from "@angular/material/sidenav";
+import { MatTreeNestedDataSource } from "@angular/material/tree";
+import { Router, RouterEvent, Event } from "@angular/router";
+import { filter } from "rxjs/operators";
+
+import { NavigationService, TreeNavNode } from 
"src/app/shared/navigation/navigation.service";
+
+/**
+ * TpSidebarComponent is the controller for the sidebar.
+ */
+@Component({
+       selector: "tp-sidebar",
+       styleUrls: ["./tp-sidebar.component.scss"],
+       templateUrl: "./tp-sidebar.component.html",
+})
+export class TpSidebarComponent implements OnInit {
+       public dataSource = new MatTreeNestedDataSource<TreeNavNode>();
+       public treeCtrl = new NestedTreeControl<TreeNavNode>(node => 
node.children);
+
+       public hidden = false;
+       private lastRoute = "";
+       private lastChild?: TreeNavNode;
+
+       /**
+        * Used in the sidebar to ensure the active page is visible.1
+        *
+        * @private
+        */
+       private childToParent = new Map<string, TreeNavNode>();
+
+       @ViewChild("sidenav") public sidenav!: MatSidenav;
+
+       /**
+        * Used by angular to determine if this node should be a nested tree 
node.
+        *
+        * @param _ Index of the current node.
+        * @param node Node to test.
+        * @returns If the node has children.
+        */
+       public hasChild(_: number, node: TreeNavNode): boolean {
+               return node.children !== undefined && node.children.length > 0;
+       }
+
+       constructor(private readonly navService: NavigationService, private 
readonly route: Router) {
+       }
+
+       /**
+        * Adds to childToParent from the given node.
+        *
+        * @param node The node to map.
+        * @private
+        */
+       private mapChild(node: TreeNavNode): void {
+               if(node.children !== undefined) {
+                       for(const child of node.children) {
+                               this.childToParent.set(this.nodeHandle(child), 
node);
+                               this.mapChild(child);
+                       }
+               }
+       }
+
+       /**
+        * Angular lifecycle hook.
+        */
+       public ngOnInit(): void {
+               this.navService.sidebarHidden.subscribe(hidden => {
+                       if(this.sidenav) {
+                               this.hidden = hidden;
+                               if(hidden && this.sidenav.opened) {
+                                       this.sidenav.close().catch(err => {
+                                               console.error(`Unable to close 
sidebar: ${err}`);
+                                       });
+                               } else if (!this.sidenav.opened) {
+                                       this.sidenav.open().catch(err => {
+                                               console.error(`Unable to open 
sidebar: ${err}`);
+                                       });
+                               }
+                       }
+               });
+               this.navService.sidebarNavs.subscribe(navs => {
+                       this.dataSource.data = navs;
+
+                       this.childToParent = new Map<string, TreeNavNode>();
+                       navs.forEach(nav => this.mapChild(nav));
+               });
+
+               this.route.events.pipe(
+                       filter((e: Event): e is RouterEvent => e instanceof 
RouterEvent)
+               ).subscribe((e: RouterEvent) => {
+                       const path = e.url.split("?")[0];
+                       if(path !== this.lastRoute) {
+                               this.lastRoute = path;
+                               for(const node of this.dataSource.data) {
+                                       for(const child of 
this.treeCtrl.getDescendants(node)) {
+                                               if(child.href === path) {
+                                                       if(this.lastChild) {
+                                                               
this.lastChild.active = false;
+                                                       }
+                                                       child.active = true;
+                                                       this.lastChild = child;
+                                                       
this.treeCtrl.expand(node);
+                                                       let parent = 
this.childToParent.get(this.nodeHandle(child));
+                                                       let depth = 0;
+                                                       while(parent !== 
undefined && depth++ < 5) {
+                                                               
this.treeCtrl.expand(parent);
+                                                               parent = 
this.childToParent.get(this.nodeHandle(parent));
+                                                       }
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+               });
+       }

Review Comment:
   If you wanna do it the easy way, then yes. Unfortunately `routerLinkActive` 
won't expand  a nested `mat-tree` so a lot of this is still needed.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to