Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#7872](https://github.com/apache/trafficcontrol/issues/7872) *Traffic Router*: Updated Apache Tomcat from 9.0.43, 9.0.67, 9.0.83, and 9.0.86 to 9.0.87.

### Fixed
- [#7998](https://github.com/apache/trafficcontrol/pull/7998) *Traffic Portalv2* Fixed (create and update) page titles across every feature
- [#7984](https://github.com/apache/trafficcontrol/pull/7984) *Traffic Ops* Fixed TO Client cert authentication with respect to returning response cookie.
- [#7957](https://github.com/apache/trafficcontrol/pull/7957) *Traffic Ops* Fix the incorrect display of delivery services assigned to ORG servers.
- [#7917](https://github.com/apache/trafficcontrol/pull/7917) *Traffic Ops* Removed `Alerts` field from struct `ProfileExportResponse`.
Expand Down
8 changes: 2 additions & 6 deletions experimental/traffic-portal/src/app/api/origin.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ export class OriginService extends APIService {
* @param originOrId The ID of the Origin to delete.
* @returns The deleted Origin.
*/
public async deleteOrigin(
originOrId: number | RequestOriginResponse
): Promise<RequestOriginResponse> {
public async deleteOrigin(originOrId: number | RequestOriginResponse): Promise<RequestOriginResponse> {
const id = typeof originOrId === "number" ? originOrId : originOrId.id;
return this.delete<RequestOriginResponse>(`origins?id=${id}`).toPromise();
}
Expand All @@ -92,9 +90,7 @@ export class OriginService extends APIService {
* @param origin The Origin to create.
* @returns The created Origin.
*/
public async createOrigin(
origin: RequestOrigin
): Promise<RequestOriginResponse> {
public async createOrigin(origin: RequestOrigin): Promise<RequestOriginResponse> {
return this.post<RequestOriginResponse>("origins", origin).toPromise();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<tp-loading *ngIf="!asn"></tp-loading>
<form ngNativeValidate (ngSubmit)="submit($event)" *ngIf="asn">
<mat-card-content class="container">
<mat-form-field *ngIf="!new">
<mat-form-field *ngIf="!isNew">
<mat-label>ID</mat-label>
<input matInput type="text" name="id" disabled readonly [defaultValue]="asn.id" />
</mat-form-field>
Expand All @@ -27,20 +27,20 @@
<mat-form-field>
<mat-label>Cache Group</mat-label>
<mat-select name="cachegroup" [(ngModel)]="asn.cachegroupId" required>
<mat-option *ngFor="let cachegroup of cachegroups" [value]="cachegroup.id">{{cachegroup.name}}</mat-option>
<mat-option *ngFor="let cachegroup of cacheGroups" [value]="cachegroup.id">{{cachegroup.name}}</mat-option>
</mat-select>
<mat-hint>
<a mat-icon-button [disabled]="!asn.cachegroupId" class="small-icon-button" matTooltip="View Cache Group Details" aria-label="View Cache Group Details" color="primary" [routerLink]="'/core/cache-groups/' + asn.cachegroupId" target="_blank">
<mat-icon>link</mat-icon>
</a>
</mat-hint>
</mat-form-field>
<mat-form-field *ngIf="!new">
<mat-form-field *ngIf="!isNew">
<mat-label>Last Updated</mat-label>
<input matInput type="text" name="lastUpdated" disabled readonly [defaultValue]="asn.lastUpdated" /> </mat-form-field>
</mat-card-content>
<mat-card-actions align="end">
<button mat-raised-button type="button" *ngIf="!new" color="warn" (click)="deleteAsn()">Delete</button>
<button mat-raised-button type="button" *ngIf="!isNew" color="warn" (click)="deleteAsn()">Delete</button>
<button mat-raised-button type="submit" color="primary">Save</button>
</mat-card-actions>
</form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ describe("AsnDetailComponent", () => {
await fixture.whenStable();
expect(paramMap).toHaveBeenCalled();
expect(component.asn).not.toBeNull();
expect(component.asn.asn).toBe(1);
expect(component.new).toBeTrue();
expect(component.asn.asn).toBe(0);
expect(component.isNew).toBeTrue();
});

it("existing asn", async () => {
Expand All @@ -72,6 +72,6 @@ describe("AsnDetailComponent", () => {
expect(paramMap).toHaveBeenCalled();
expect(component.asn).not.toBeNull();
expect(component.asn.asn).toBe(0);
expect(component.new).toBeFalse();
expect(component.isNew).toBeFalse();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Location } from "@angular/common";

import { Component, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute } from "@angular/router";
import { ActivatedRoute, Router } from "@angular/router";
import { ResponseASN, ResponseCacheGroup } from "trafficops-types";

import { CacheGroupService } from "src/app/api";
Expand All @@ -31,16 +31,16 @@ import { NavigationService } from "src/app/shared/navigation/navigation.service"
templateUrl: "./asn-detail.component.html"
})
export class ASNDetailComponent implements OnInit {
public new = false;
public isNew = false;
public asn!: ResponseASN;
public cachegroups!: Array<ResponseCacheGroup>;
public cacheGroups = new Array<ResponseCacheGroup>();

constructor(
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly cacheGroupService: CacheGroupService,
private readonly location: Location,
private readonly dialog: MatDialog,
private readonly header: NavigationService,
private readonly navSvc: NavigationService,
private readonly log: LoggingService,
) {
}
Expand All @@ -49,21 +49,28 @@ export class ASNDetailComponent implements OnInit {
* Angular lifecycle hook where data is initialized.
*/
public async ngOnInit(): Promise<void> {
this.cachegroups = await this.cacheGroupService.getCacheGroups();
this.cacheGroupService.getCacheGroups().then(
cgs => {
this.cacheGroups = cgs;
}
);

const ID = this.route.snapshot.paramMap.get("id");
if (ID === null) {
this.log.error("missing required route parameter 'id'");
return;
}

if (ID === "new") {
this.header.headerTitle.next("New ASN");
this.new = true;
this.isNew = ID === "new";

if (this.isNew) {
this.setTitle();
this.isNew = true;
this.asn = {
asn: 1,
cachegroup: "test",
cachegroupId: 1,
id: 1,
asn: 0,
cachegroup: "",
cachegroupId: 0,
id: 0,
lastUpdated: new Date()
};
return;
Expand All @@ -75,25 +82,39 @@ export class ASNDetailComponent implements OnInit {
}

this.asn = await this.cacheGroupService.getASNs(numID);
this.header.headerTitle.next(`ASN: ${this.asn.asn}`);
this.setTitle();
}

/**
* Sets the headerTitle based on current ASN state.
*
* @private
*/
private setTitle(): void {
const title = this.isNew ? "New ASN" : `ASN: ${this.asn.asn}`;
this.navSvc.headerTitle.next(title);
}

/**
* Deletes the current ASN.
*/
public async deleteAsn(): Promise<void> {
if (this.new) {
if (this.isNew) {
this.log.error("Unable to delete new ASN");
return;
}
if(!this.asn.asn) {
this.log.error("Missing ASN number");
return;
}
const ref = this.dialog.open(DecisionDialogComponent, {
data: {message: `Are you sure you want to delete ASN ${this.asn.asn} with id ${this.asn.id}`,
title: "Confirm Delete"}
});
ref.afterClosed().subscribe(result => {
if(result) {
this.cacheGroupService.deleteASN(this.asn.id);
this.location.back();
this.router.navigate(["core/asns"]);
}
});
}
Expand All @@ -106,12 +127,14 @@ export class ASNDetailComponent implements OnInit {
public async submit(e: Event): Promise<void> {
e.preventDefault();
e.stopPropagation();
if(this.new) {
if(this.isNew) {
this.asn = await this.cacheGroupService.createASN(this.asn);
this.new = false;
this.isNew = false;
await this.router.navigate(["core/asns", this.asn.id]);
} else {
this.asn = await this.cacheGroupService.updateASN(this.asn);
}
this.setTitle();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ export class ASNsTableComponent implements OnInit {

constructor(
private readonly route: ActivatedRoute,
private readonly headerSvc: NavigationService,
private readonly navSvc: NavigationService,
private readonly api: CacheGroupService,
private readonly dialog: MatDialog,
public readonly auth: CurrentUserService,
private readonly log: LoggingService,
) {
this.fuzzySubject = new BehaviorSubject<string>("");
this.asns = this.api.getASNs();
this.headerSvc.headerTitle.next("ASNs");
this.navSvc.headerTitle.next("ASNs");
}

/** Initializes table data, loading it from Traffic Ops. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,11 @@ describe("CacheGroupDetailsComponent", () => {
imports: [
APITestingModule,
RouterTestingModule.withRoutes([
{
component: CacheGroupDetailsComponent,
path: ""
},
{
component: CacheGroupDetailsComponent,
path: "cache-groups/:id"
}
{component: CacheGroupDetailsComponent, path: "core/cache-groups/:id"},
{component: CacheGroupDetailsComponent, path: "core/cache-groups"}
]),
MatDialogModule,
NoopAnimationsModule,

],
providers: [ { provide: NavigationService, useValue: navSvc } ]
}).compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@
* limitations under the License.
*/

import { Location } from "@angular/common";
import { Component, type OnInit } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import { FormControl } from "@angular/forms";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute } from "@angular/router";
import { LocalizationMethod, localizationMethodToString, TypeFromResponse, type ResponseCacheGroup } from "trafficops-types";
import { ActivatedRoute, Router } from "@angular/router";
import { LocalizationMethod, localizationMethodToString, TypeFromResponse, ResponseCacheGroup } from "trafficops-types";

import { CacheGroupService, TypeService } from "src/app/api";
import { DecisionDialogComponent, type DecisionDialogData } from "src/app/shared/dialogs/decision-dialog/decision-dialog.component";
import { DecisionDialogComponent, DecisionDialogData } from "src/app/shared/dialogs/decision-dialog/decision-dialog.component";
import { LoggingService } from "src/app/shared/logging.service";
import { NavigationService } from "src/app/shared/navigation/navigation.service";

Expand Down Expand Up @@ -69,9 +68,9 @@ export class CacheGroupDetailsComponent implements OnInit {

constructor(
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly api: CacheGroupService,
private readonly typesAPI: TypeService,
private readonly location: Location,
private readonly dialog: MatDialog,
private readonly navSvc: NavigationService,
private readonly log: LoggingService,
Expand Down Expand Up @@ -182,7 +181,7 @@ export class CacheGroupDetailsComponent implements OnInit {
ref.afterClosed().subscribe(result => {
if (result) {
this.api.deleteCacheGroup(this.cacheGroup);
this.location.replaceState("core/cache-groups");
this.router.navigate(["core/cache-groups"]);
}
});
}
Expand All @@ -208,6 +207,7 @@ export class CacheGroupDetailsComponent implements OnInit {
if (this.new) {
this.cacheGroup = await this.api.createCacheGroup(this.cacheGroup);
this.new = false;
await this.router.navigate(["core/cache-groups", this.cacheGroup.id]);
} else {
this.cacheGroup = await this.api.updateCacheGroup(this.cacheGroup);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
* limitations under the License.
*/

import { Location } from "@angular/common";
import { Component, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute } from "@angular/router";
import { ActivatedRoute, Router } from "@angular/router";
import { ResponseCoordinate } from "trafficops-types";

import { CacheGroupService } from "src/app/api";
Expand All @@ -37,8 +36,8 @@ export class CoordinateDetailComponent implements OnInit {

constructor(
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly cacheGroupService: CacheGroupService,
private readonly location: Location,
private readonly dialog: MatDialog,
private readonly navSvc: NavigationService,
private readonly log: LoggingService,
Expand All @@ -54,8 +53,10 @@ export class CoordinateDetailComponent implements OnInit {
return;
}

if (ID === "new") {
this.navSvc.headerTitle.next("New Coordinate");
this.new = ID === "new";

if (this.new) {
this.setTitle();
this.new = true;
this.coordinate = {
id: -1,
Expand All @@ -73,7 +74,17 @@ export class CoordinateDetailComponent implements OnInit {
}

this.coordinate = await this.cacheGroupService.getCoordinates(numID);
this.navSvc.headerTitle.next(`Coordinate: ${this.coordinate.name}`);
this.setTitle();
}

/**
* Sets the headerTitle based on current Coordinate state.
*
* @private
*/
private setTitle(): void {
const title = this.new ? "New Coordinate" : `Coordinate: ${this.coordinate.name}`;
this.navSvc.headerTitle.next(title);
}

/**
Expand All @@ -91,7 +102,7 @@ export class CoordinateDetailComponent implements OnInit {
ref.afterClosed().subscribe(result => {
if(result) {
this.cacheGroupService.deleteCoordinate(this.coordinate.id);
this.location.back();
this.router.navigate(["core/coordinates"]);
}
});
}
Expand All @@ -107,9 +118,11 @@ export class CoordinateDetailComponent implements OnInit {
if(this.new) {
this.coordinate = await this.cacheGroupService.createCoordinate(this.coordinate);
this.new = false;
await this.router.navigate(["core/coordinates", this.coordinate.id]);
} else {
this.coordinate = await this.cacheGroupService.updateCoordinate(this.coordinate);
}
this.setTitle();
}

}
Loading