[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-08-01 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1280757970


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,44 @@
+
+
+   
+   
+   
+   
+   Name
+   
+   
+   
+   Description
+   

Review Comment:
   Using `[(ngModel)]` in 4fbced122d



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-31 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1279957834


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,155 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+import { TopologyService as ConcreteService, TopTreeNode } from "src/app/api";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   },
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The unique name of a single Topology to be returned
+* @returns Either an Array of Topologies or a single Topology, 
depending on whether `name` was
+* passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   if (name !== undefined) {
+   const topology = this.topologies.find(t => t.name === 
name);
+   if (!topology) {
+   throw new Error(`no such Topology ${name}`);
+   }
+   return topology;
+   }
+   return this.topologies;
+   }

Review Comment:
   I have a strong preference to not change the concrete service this late in 
the review cycle. Matching the call signature in a5a39eca0



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-31 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1279957947


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,44 @@
+
+
+   
+   
+   
+   
+   Name
+   

Review Comment:
   That was unintentional, made the `name` field mutable in 3cb606508.



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-31 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1279957947


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,44 @@
+
+
+   
+   
+   
+   
+   Name
+   

Review Comment:
   That was unintentional, made the `name` field mutable in 3cb6065082.



##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,155 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+import { TopologyService as ConcreteService, TopTreeNode } from "src/app/api";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   },
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The unique name of a single Topology to be returned
+* @returns Either an Array of Topologies or a single Topology, 
depending on whether `name` was
+* passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   if (name !== undefined) {
+   const topology = this.topologies.find(t => t.name === 
name);
+   if (!topology) {
+   throw new Error(`no such Topology ${name}`);
+   }
+   return topology;
+   }
+   return this.topologies;
+   }

Review Comment:
   I have a strong preference to not change the concrete service this late in 
the review cycle. Matching the call signature in a5a39eca00



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-31 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1279892473


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets a specific Topology from Traffic Ops
+*
+* @param name The name of the Topology to be returned.
+* @returns The Topology with the given name.
+*/
+   public async getTopologies(name: string): Promise;
+   /**
+* Gets all Topologies from Traffic Ops
+*
+* @returns An Array of all Topologies configured in Traffic Ops.
+*/
+   public async getTopologies(): Promise>;
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns Either an Array of Topology objects, or a single Topology, 
depending on
+* whether `name` was   passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   const path = "topologies";
+   if (name) {
+   const topology = await 
this.get<[ResponseTopology]>(path, undefined, {name}).toPromise();
+   if (topology.length !== 1) {
+   throw new Error(`${topology.length} Topologies 
found by name ${name}`);
+   }
+   return topology[0];
+   }
+   return this.get>(path).toPromise();
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its name.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   return this.delete(`topologies?name=${name}`).toPromise();
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   return this.post("topologies", 
topology).toPromise();
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being updated
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   return 
this.put(`topologies?name=${topology.name}`, 
topology).toPromise();
+   }
+
+   /**
+* Generates a material tree from a topology.
+*
+* @param topology The topology to generate a material tree from.
+* @returns a material tree.
+*/
+   public topologyToTree(topology: ResponseTopology): Array {
+   const treeNodes: Array = [];
+   const topLevel: Array = [];
+   for (const node of topology.nodes) {
+   const name = node.cachegroup;
+   const cachegroup = node.cachegroup;
+   const children: Array = [];
+   const parents: Array = [];
+   treeNodes.push({
+   cachegroup,
+   children,
+   name,
+   parents,
+   });
+   }
+   for (let index = 0; index < topology.nodes.length; index++) {
+   const node = topology.nodes[index];
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-28 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1278017282


##
experimental/traffic-portal/src/app/core/core.module.ts:
##
@@ -116,6 +116,7 @@ export const ROUTES: Routes = [
{ component: ProfileDetailComponent, path: "profiles/:id"},
{ component: ProfileTableComponent, path: "profiles"},
{ component: TopologyDetailsComponent, path: "topologies/:name"},
+   { component: TopologyDetailsComponent, path: "topologies-new"},

Review Comment:
   Changed to `new-topology` in b175ed8689



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-28 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1278016555


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.spec.ts:
##
@@ -0,0 +1,70 @@
+/*
+* 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 { ComponentFixture, TestBed } from "@angular/core/testing";
+import { MatDialogModule } from "@angular/material/dialog";
+import { ActivatedRoute } from "@angular/router";
+import { RouterTestingModule } from "@angular/router/testing";
+import { ReplaySubject } from "rxjs";
+
+import { APITestingModule } from "src/app/api/testing";
+import {
+   NavigationService
+} from "src/app/shared/navigation/navigation.service";
+
+import { TopologyDetailsComponent } from "./topology-details.component";
+
+describe("TopologyDetailsComponent", () => {
+   let component: TopologyDetailsComponent;
+   let fixture: ComponentFixture;
+   let route: ActivatedRoute;
+   let paramMap: jasmine.Spy;
+
+   const navSvc = jasmine.createSpyObj([], {
+   headerHidden: new ReplaySubject(),
+   headerTitle: new ReplaySubject(),
+   });
+
+   beforeEach(async () => {
+   TestBed.configureTestingModule({
+   declarations: [TopologyDetailsComponent],
+   imports: [APITestingModule, RouterTestingModule, 
MatDialogModule],
+   providers: [{provide: NavigationService, useValue: 
navSvc}],
+   });
+   route = TestBed.inject(ActivatedRoute);
+   paramMap = spyOn(route.snapshot.paramMap, "get");
+   paramMap.and.returnValue(null);
+   fixture = TestBed.createComponent(TopologyDetailsComponent);
+   component = fixture.componentInstance;
+   fixture.detectChanges();
+   await fixture.whenStable();
+   });
+
+   it("should create", () => {
+   expect(component).toBeTruthy();
+   expect(paramMap).toHaveBeenCalled();
+   });
+
+   it("existing topology", async () => {
+   paramMap.and.returnValue("test");
+
+   fixture = TestBed.createComponent(TopologyDetailsComponent);
+   component = fixture.componentInstance;
+   fixture.detectChanges();
+   await fixture.whenStable();
+   expect(paramMap).toHaveBeenCalled();
+   expect(component.topology).toBeInstanceOf(Object);

Review Comment:
   Using `.toBeDefined()` in f56ae13cc1



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-28 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1278016317


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,185 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns An Array of Topologies
+* whether `name` was   passed.

Review Comment:
   Whitespace fixed in 4b9352e801



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-28 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1278016070


##
experimental/traffic-portal/src/app/api/topology.service.spec.ts:
##
@@ -0,0 +1,70 @@
+/**

Review Comment:
   `topology.service` coverage increased to 100% in 0e5b61c515



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-27 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1276243223


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*

Review Comment:
   Added some test coverage.



##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.spec.ts:
##
@@ -0,0 +1,55 @@
+/*
+* 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 { ComponentFixture, TestBed } from "@angular/core/testing";
+import { MatDialogModule } from "@angular/material/dialog";
+import { ActivatedRoute } from "@angular/router";
+import { RouterTestingModule } from "@angular/router/testing";
+import { ReplaySubject } from "rxjs";
+
+import { APITestingModule } from "src/app/api/testing";
+import {
+   NavigationService
+} from "src/app/shared/navigation/navigation.service";
+
+import { TopologyDetailsComponent } from "./topology-details.component";
+
+describe("TopologyDetailsComponent", () => {
+   let component: TopologyDetailsComponent;
+   let fixture: ComponentFixture;
+   let route: ActivatedRoute;
+   let paramMap: jasmine.Spy;
+
+   const navSvc = jasmine.createSpyObj([], {
+   headerHidden: new ReplaySubject(),
+   headerTitle: new ReplaySubject(),
+   });
+
+   beforeEach(() => {
+   TestBed.configureTestingModule({
+   declarations: [TopologyDetailsComponent],
+   imports: [APITestingModule, RouterTestingModule, 
MatDialogModule],
+   providers: [{provide: NavigationService, useValue: 
navSvc}],
+   });
+   route = TestBed.inject(ActivatedRoute);
+   paramMap = spyOn(route.snapshot.paramMap, "get");
+   paramMap.and.returnValue(null);
+   fixture = TestBed.createComponent(TopologyDetailsComponent);
+   component = fixture.componentInstance;
+   fixture.detectChanges();
+   });
+
+   it("should create", () => {
+   expect(component).toBeTruthy();
+   });

Review Comment:
   Added *existing topology* test.



##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.spec.ts:
##
@@ -0,0 +1,55 @@
+/*
+* 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 { ComponentFixture, TestBed } from "@angular/core/testing";
+import { MatDialogModule } from "@angular/material/dialog";
+import { ActivatedRoute } from "@angular/router";
+import { RouterTestingModule } from "@angular/router/testing";
+import { ReplaySubject } from "rxjs";
+
+import { APITestingModule } from "src/app/api/testing";
+import {
+   NavigationService
+} from "src/app/shared/navigation/navigation.service";
+
+import { TopologyDetailsComponent } from "./topology-details.component";
+
+describe("TopologyDetailsComponent", () => {
+   let component: TopologyDetailsComponent;
+   let fixture: ComponentFixture;
+   let route: ActivatedRoute;
+   let paramMap: jasmine.Spy;

Review Comment:
   Using `paramMap` (and `route`) in test *existing topology*.



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-27 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1276243540


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.ts:
##
@@ -0,0 +1,152 @@
+/*
+* 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 { Location } from "@angular/common";
+import { Component, OnInit } from "@angular/core";
+import { MatDialog } from "@angular/material/dialog";
+import { MatTreeNestedDataSource } from "@angular/material/tree";
+import { ActivatedRoute } from "@angular/router";
+import { ResponseTopology } from "trafficops-types";
+
+import { TopologyService, TopTreeNode } from "src/app/api";
+import {
+   DecisionDialogComponent,
+   DecisionDialogData,
+} from "src/app/shared/dialogs/decision-dialog/decision-dialog.component";
+import {
+   NavigationService
+} from "src/app/shared/navigation/navigation.service";
+
+/**
+ * TopologyDetailComponent is the controller for a Topology's "detail" page.
+ */
+@Component({
+   selector: "tp-topology-details",
+   styleUrls: ["./topology-details.component.scss"],
+   templateUrl: "./topology-details.component.html",
+})
+export class TopologyDetailsComponent implements OnInit {
+   public new = false;
+   public topology: ResponseTopology = {
+   description: "",
+   lastUpdated: new Date(),
+   name: "",
+   nodes: [],
+   };
+   public showErrors = false;
+   public topologies: Array = [];
+   public topologySource = new MatTreeNestedDataSource();
+   public topologyControl = new NestedTreeControl(node => 
node.children);
+
+   constructor(
+   private readonly route: ActivatedRoute,
+   private readonly api: TopologyService,
+   private readonly location: Location,
+   private readonly dialog: MatDialog,
+   private readonly navSvc: NavigationService,
+   ) {
+   }
+
+   /**
+* Angular lifecycle hook where data is initialized.
+*/
+   public async ngOnInit(): Promise {
+   const name = this.route.snapshot.paramMap.get("name");
+   if (name === null) {
+   console.error("missing required route parameter 
'name'");
+   return;
+   }
+
+   const topologiesPromise = 
this.api.getTopologies().then(topologies => this.topologies = topologies);
+   if (name === "new") {

Review Comment:
   Now a new topology is created at `/core/topologies-new`.



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-27 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1276242940


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {

Review Comment:
   Added `topologyToTree` and `treeToTopology` to the testing service.



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273698139


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets a specific Topology from Traffic Ops
+*
+* @param name The name of the Topology to be returned.
+* @returns The Topology with the given name.
+*/
+   public async getTopologies(name: string): Promise;
+   /**
+* Gets all Topologies from Traffic Ops
+*
+* @returns An Array of all Topologies configured in Traffic Ops.
+*/
+   public async getTopologies(): Promise>;
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns Either an Array of Topology objects, or a single Topology, 
depending on
+* whether `name` was   passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   const path = "topologies";
+   if (name) {
+   const topology = await 
this.get<[ResponseTopology]>(path, undefined, {name}).toPromise();
+   if (topology.length !== 1) {
+   throw new Error(`${topology.length} Topologies 
found by name ${name}`);
+   }
+   return topology[0];
+   }
+   return this.get>(path).toPromise();
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its name.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   return this.delete(`topologies?name=${name}`).toPromise();
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   return this.post("topologies", 
topology).toPromise();
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being updated
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   return 
this.put(`topologies?name=${topology.name}`, 
topology).toPromise();
+   }
+
+   /**
+* Generates a material tree from a topology.
+*
+* @param topology The topology to generate a material tree from.
+* @returns a material tree.
+*/
+   public topologyToTree(topology: ResponseTopology): Array {
+   const treeNodes: Array = [];
+   const topLevel: Array = [];
+   for (const node of topology.nodes) {
+   const name = node.cachegroup;
+   const cachegroup = node.cachegroup;
+   const children: Array = [];
+   const parents: Array = [];
+   treeNodes.push({
+   cachegroup,
+   children,
+   name,
+   parents,
+   });
+   }
+   for (let index = 0; index < topology.nodes.length; index++) {
+   const node = topology.nodes[index];
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273679698


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   }
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name? The integral, unique identifier of a single Topology to 
be
+* returned
+* @returns Either a Map of Topology names to full Topology objects, or 
a single Topology, depending on whether `id` was

Review Comment:
   Reworded `@returns`



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273678837


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,45 @@
+
+
+   
+   
+   
+   
+   Name
+   
+   
+   
+   Description
+   
+   
+   
+   
+   
+   
+   
+   {{node.name}}
+   
+   
+   
+   
+   

Review Comment:
   Unused line removed



##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,45 @@
+
+
+   
+   
+   
+   
+   Name
+   

Review Comment:
   Using `[value]` now



##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,45 @@
+
+
+   

Review Comment:
   Changed to
   
   ```html

   ```
   
   but it's worth noting that a lot of code got merged that does the thing you 
want to avoid:
   
   ```
   $ git grep '
   
src/app/core/cache-groups/cache-group-details/cache-group-details.component.html:
   
   
src/app/core/cache-groups/coordinates/detail/coordinate-detail.component.html:  

   src/app/core/cache-groups/divisions/detail/division-detail.component.html:   
   
   src/app/core/cache-groups/regions/detail/region-detail.component.html:  

   src/app/core/cdns/cdn-detail/cdn-detail.component.html: 
   src/app/core/parameters/detail/parameter-detail.component.html: 
   
src/app/core/servers/capabilities/capability-details/capability-details.component.html:
 
   src/app/core/servers/phys-loc/detail/phys-loc-detail.component.html:

   src/app/core/servers/server-details/server-details.component.html:  

   src/app/core/types/detail/type-detail.component.html:   
   src/app/core/users/roles/detail/role-detail.component.html: 
   src/app/core/users/tenants/tenant-details/tenant-details.component.html: 
   
   src/app/core/users/user-details/user-details.component.html:
   ```



-- 
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: issues-unsubscr...@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273677580


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   }
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name? The integral, unique identifier of a single Topology to 
be
+* returned
+* @returns Either a Map of Topology names to full Topology objects, or 
a single Topology, depending on whether `id` was
+*  passed.
+* (In the event that `id` is passed but does not match any Topology, 
`null` will be emitted)
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   if (name !== undefined) {
+   const topology = this.topologies.find(t => t.name === 
name);
+   if (!topology) {
+   throw new Error(`no such Topology #${name}`);
+   }
+   return topology;
+   }
+   return this.topologies;
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its ID.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   const idx = this.topologies.findIndex(t => t.name === name);
+   if (idx < 0) {
+   throw new Error(`no such Topology: #${name}`);
+   }
+   this.topologies.splice(idx, 1);
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   const nodes: ResponseTopologyNode[] = topology.nodes.map(node 
=> {
+   if (!(node.parents instanceof Array)) {
+   node.parents = [];
+   }
+   const responseNode: ResponseTopologyNode = {
+   cachegroup: node.cachegroup,
+   parents: node.parents || [],
+   };
+   return responseNode;
+   });
+   const t: ResponseTopology = {
+   description: topology.description || "",
+   lastUpdated: new Date(),
+   name: topology.name,
+   nodes,
+   };
+   this.topologies.push(t);
+   return t;
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being
+* updated, or just its ID.
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   const idx = this.topologies.findIndex(t => t.name === 
topology.name);
+   topology = {
+   ...topology,
+   lastUpdated: new Date()
+   };
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273679183


##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.html:
##
@@ -0,0 +1,45 @@
+
+
+   
+   

Review Comment:
   Removed the `ngIf`, but again, a lot of code got merged that does this:
   
   ```
   $ git grep '
   
src/app/core/cache-groups/cache-group-details/cache-group-details.component.html:
   
   
src/app/core/cache-groups/coordinates/detail/coordinate-detail.component.html:  

   src/app/core/cache-groups/divisions/detail/division-detail.component.html:   
   
   src/app/core/cache-groups/regions/detail/region-detail.component.html:  

   src/app/core/cdns/cdn-detail/cdn-detail.component.html: 
   src/app/core/parameters/detail/parameter-detail.component.html: 
   src/app/core/profiles/profile-detail/profile-detail.component.html: 

   
src/app/core/servers/capabilities/capability-details/capability-details.component.html:
 
   src/app/core/servers/phys-loc/detail/phys-loc-detail.component.html:

   src/app/core/types/detail/type-detail.component.html:   
   src/app/core/users/roles/detail/role-detail.component.html: 
   src/app/core/users/tenants/tenant-details/tenant-details.component.html: 
   
   src/app/core/users/user-details/user-details.component.html:
   ```



##
experimental/traffic-portal/src/app/core/topologies/topology-details/topology-details.component.ts:
##
@@ -0,0 +1,152 @@
+/*
+* 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 { Location } from "@angular/common";
+import { Component, OnInit } from "@angular/core";
+import { MatDialog } from "@angular/material/dialog";
+import { MatTreeNestedDataSource } from "@angular/material/tree";
+import { ActivatedRoute } from "@angular/router";
+import { ResponseTopology } from "trafficops-types";
+
+import { TopologyService, TopTreeNode } from "src/app/api";
+import {
+   DecisionDialogComponent,
+   DecisionDialogData,
+} from "src/app/shared/dialogs/decision-dialog/decision-dialog.component";
+import {
+   NavigationService
+} from "src/app/shared/navigation/navigation.service";
+
+/**
+ * TopologyDetailComponent is the controller for a Topology's "detail" page.
+ */
+@Component({
+   selector: "tp-topology-details",
+   styleUrls: ["./topology-details.component.scss"],
+   templateUrl: "./topology-details.component.html",
+})
+export class TopologyDetailsComponent implements OnInit {
+   public new = false;
+   public topology: ResponseTopology = {
+   description: "",
+   lastUpdated: new Date(),
+   name: "",
+   nodes: [],
+   };
+   public showErrors = false;
+   public topologies: Array = [];
+   public topologySource = new MatTreeNestedDataSource();
+   public topologyControl = new NestedTreeControl(node => 
node.children);
+
+   constructor(
+   private readonly route: ActivatedRoute,
+   private readonly api: TopologyService,
+   private readonly location: Location,
+   private readonly dialog: MatDialog,
+   private readonly navSvc: NavigationService,
+   ) {
+   }
+
+   /**
+* Angular lifecycle hook where data is initialized.
+*/
+   public async ngOnInit(): Promise {
+   const name = this.route.snapshot.paramMap.get("name");
+   if (name === null) {
+   console.error("missing required route parameter 
'name'");
+   return;
+   }
+
+   const topologiesPromise = 
this.api.getTopologies().then(topologies => this.topologies = topologies);
+   if (name === "new") {
+   this.new = true;
+   this.setTitle();
+   await topologiesPromise;
+   return;
+   }
+   await topologiesPromise;
+   const index = this.topologies.findIndex(c => c.name === name);
+   if (index < 0) {
+   console.error(`no such Topology: #${name}`);
+   return;
+   }
+   this.topology = this.topologies.splice(index, 1)[0];
+   this.topologySource.data = 

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273678356


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets a specific Topology from Traffic Ops
+*
+* @param name The name of the Topology to be returned.
+* @returns The Topology with the given name.
+*/
+   public async getTopologies(name: string): Promise;
+   /**
+* Gets all Topologies from Traffic Ops
+*
+* @returns An Array of all Topologies configured in Traffic Ops.
+*/
+   public async getTopologies(): Promise>;
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns Either an Array of Topology objects, or a single Topology, 
depending on
+* whether `name` was   passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   const path = "topologies";
+   if (name) {
+   const topology = await 
this.get<[ResponseTopology]>(path, undefined, {name}).toPromise();
+   if (topology.length !== 1) {
+   throw new Error(`${topology.length} Topologies 
found by name ${name}`);
+   }
+   return topology[0];
+   }
+   return this.get>(path).toPromise();
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its name.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   return this.delete(`topologies?name=${name}`).toPromise();
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   return this.post("topologies", 
topology).toPromise();
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being updated
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   return 
this.put(`topologies?name=${topology.name}`, 
topology).toPromise();
+   }
+
+   /**
+* Generates a material tree from a topology.
+*
+* @param topology The topology to generate a material tree from.
+* @returns a material tree.
+*/
+   public topologyToTree(topology: ResponseTopology): Array {
+   const treeNodes: Array = [];
+   const topLevel: Array = [];
+   for (const node of topology.nodes) {
+   const name = node.cachegroup;
+   const cachegroup = node.cachegroup;
+   const children: Array = [];
+   const parents: Array = [];
+   treeNodes.push({
+   cachegroup,
+   children,
+   name,
+   parents,
+   });
+   }
+   for (let index = 0; index < topology.nodes.length; index++) {
+   const node = topology.nodes[index];
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273677888


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets a specific Topology from Traffic Ops
+*
+* @param name The name of the Topology to be returned.
+* @returns The Topology with the given name.
+*/
+   public async getTopologies(name: string): Promise;
+   /**
+* Gets all Topologies from Traffic Ops
+*
+* @returns An Array of all Topologies configured in Traffic Ops.
+*/
+   public async getTopologies(): Promise>;
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns Either an Array of Topology objects, or a single Topology, 
depending on
+* whether `name` was   passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   const path = "topologies";
+   if (name) {
+   const topology = await 
this.get<[ResponseTopology]>(path, undefined, {name}).toPromise();
+   if (topology.length !== 1) {
+   throw new Error(`${topology.length} Topologies 
found by name ${name}`);
+   }
+   return topology[0];
+   }
+   return this.get>(path).toPromise();
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its name.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   return this.delete(`topologies?name=${name}`).toPromise();
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   return this.post("topologies", 
topology).toPromise();
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being updated
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   return 
this.put(`topologies?name=${topology.name}`, 
topology).toPromise();
+   }
+
+   /**
+* Generates a material tree from a topology.
+*
+* @param topology The topology to generate a material tree from.
+* @returns a material tree.
+*/
+   public topologyToTree(topology: ResponseTopology): Array {
+   const treeNodes: Array = [];
+   const topLevel: Array = [];
+   for (const node of topology.nodes) {
+   const name = node.cachegroup;
+   const cachegroup = node.cachegroup;
+   const children: Array = [];
+   const parents: Array = [];
+   treeNodes.push({
+   cachegroup,
+   children,
+   name,
+   parents,
+   });
+   }
+   for (let index = 0; index < topology.nodes.length; index++) {
+   const node = topology.nodes[index];
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273677206


##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* 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 { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import type {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode,
+} from "trafficops-types";
+
+import { APIService } from "./base-api.service";
+
+/**
+ * TopTreeNode is used to represent a topology in a format usable as a material
+ * nested tree data source.
+ */
+export interface TopTreeNode {
+   name: string;
+   cachegroup: string;
+   children: Array;
+   parents: Array;
+}
+
+/**
+ * TopologyService exposes API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService extends APIService {
+
+   constructor(http: HttpClient) {
+   super(http);
+   }
+
+   /**
+* Gets a specific Topology from Traffic Ops
+*
+* @param name The name of the Topology to be returned.
+* @returns The Topology with the given name.
+*/
+   public async getTopologies(name: string): Promise;
+   /**
+* Gets all Topologies from Traffic Ops
+*
+* @returns An Array of all Topologies configured in Traffic Ops.
+*/
+   public async getTopologies(): Promise>;
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name The name of a single Topology to be returned.
+* @returns Either an Array of Topology objects, or a single Topology, 
depending on
+* whether `name` was   passed.
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   const path = "topologies";
+   if (name) {
+   const topology = await 
this.get<[ResponseTopology]>(path, undefined, {name}).toPromise();
+   if (topology.length !== 1) {
+   throw new Error(`${topology.length} Topologies 
found by name ${name}`);
+   }
+   return topology[0];
+   }
+   return this.get>(path).toPromise();
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its name.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   return this.delete(`topologies?name=${name}`).toPromise();
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   return this.post("topologies", 
topology).toPromise();
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being updated
+*/
+   public async updateTopology(topology: ResponseTopology): 
Promise {
+   return 
this.put(`topologies?name=${topology.name}`, 
topology).toPromise();
+   }
+
+   /**
+* Generates a material tree from a topology.
+*
+* @param topology The topology to generate a material tree from.
+* @returns a material tree.
+*/
+   public topologyToTree(topology: ResponseTopology): Array {
+   const treeNodes: Array = [];
+   const topLevel: Array = [];
+   for (const node of topology.nodes) {
+   const name = node.cachegroup;
+   const cachegroup = node.cachegroup;
+   const children: Array = [];
+   const parents: Array = [];
+   treeNodes.push({
+   cachegroup,
+   children,
+   name,
+   parents,
+   });
+   }
+   for (let index = 0; index < topology.nodes.length; index++) {
+   const node = topology.nodes[index];
+

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273676836


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   }
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name? The integral, unique identifier of a single Topology to 
be
+* returned
+* @returns Either a Map of Topology names to full Topology objects, or 
a single Topology, depending on whether `id` was
+*  passed.
+* (In the event that `id` is passed but does not match any Topology, 
`null` will be emitted)
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   if (name !== undefined) {
+   const topology = this.topologies.find(t => t.name === 
name);
+   if (!topology) {
+   throw new Error(`no such Topology #${name}`);
+   }
+   return topology;
+   }
+   return this.topologies;
+   }
+
+   /**
+* Deletes a Topology.
+*
+* @param topology The Topology to be deleted, or just its ID.
+*/
+   public async deleteTopology(topology: ResponseTopology | string): 
Promise {
+   const name = typeof topology === "string" ? topology : 
topology.name;
+   const idx = this.topologies.findIndex(t => t.name === name);
+   if (idx < 0) {
+   throw new Error(`no such Topology: #${name}`);
+   }
+   this.topologies.splice(idx, 1);
+   }
+
+   /**
+* Creates a new Topology.
+*
+* @param topology The Topology to create.
+*/
+   public async createTopology(topology: RequestTopology): 
Promise {
+   const nodes: ResponseTopologyNode[] = topology.nodes.map(node 
=> {
+   if (!(node.parents instanceof Array)) {
+   node.parents = [];
+   }
+   const responseNode: ResponseTopologyNode = {
+   cachegroup: node.cachegroup,
+   parents: node.parents || [],
+   };
+   return responseNode;
+   });
+   const t: ResponseTopology = {
+   description: topology.description || "",
+   lastUpdated: new Date(),
+   name: topology.name,
+   nodes,
+   };
+   this.topologies.push(t);
+   return t;
+   }
+
+   /**
+* Replaces an existing Topology with the provided new definition of a
+* Topology.
+*
+* @param topology The full new definition of the Topology being
+* updated, or just its ID.

Review Comment:
   Changed to `name`, reworded description



##
experimental/traffic-portal/src/app/api/topology.service.ts:
##
@@ -0,0 +1,196 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You 

[GitHub] [trafficcontrol] zrhoffman commented on a diff in pull request #7615: Traffic Portal v2 Topologies details page

2023-07-25 Thread via GitHub


zrhoffman commented on code in PR #7615:
URL: https://github.com/apache/trafficcontrol/pull/7615#discussion_r1273676562


##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   }
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name? The integral, unique identifier of a single Topology to 
be

Review Comment:
   > I think this is a valid JSDoc, but you don't need to put the `?` in the 
param name. It's not a linter error, so I'm fine with this if you want to keep 
it, but it's not done anywhere else, and the compiler keeps track of what is 
actually optional or not without that needing to be spelled out in the comment.
   
   `?` removed
   
   
   > Identifiers for Topologies are not integral.
   
   Removed *integral*



##
experimental/traffic-portal/src/app/api/testing/topology.service.ts:
##
@@ -0,0 +1,130 @@
+/*
+* 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 { Injectable } from "@angular/core";
+import {
+   RequestTopology,
+   ResponseTopology,
+   ResponseTopologyNode
+} from "trafficops-types";
+
+/**
+ * TopologyService expose API functionality relating to Topologies.
+ */
+@Injectable()
+export class TopologyService {
+   private readonly topologies: ResponseTopology[] = [
+   {
+   description: "",
+   lastUpdated: new Date(),
+   name: "test",
+   nodes: [
+   {
+   cachegroup: "Edge",
+   parents: [1],
+   },
+   {
+   cachegroup: "Mid",
+   parents: [2],
+   },
+   {
+   cachegroup: "Origin",
+   parents: [],
+   },
+   ],
+   }
+   ];
+
+   /**
+* Gets one or all Topologies from Traffic Ops
+*
+* @param name? The integral, unique identifier of a single Topology to 
be
+* returned
+* @returns Either a Map of Topology names to full Topology objects, or 
a single Topology, depending on whether `id` was
+*  passed.
+* (In the event that `id` is passed but does not match any Topology, 
`null` will be emitted)
+*/
+   public async getTopologies(name?: string): 
Promise | ResponseTopology> {
+   if (name !== undefined) {
+   const topology = this.topologies.find(t => t.name