This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 0dc1ddfb89 Tpv2/regions (#7243)
0dc1ddfb89 is described below
commit 0dc1ddfb8963a38b24aed867485830559b9e1a06
Author: Kurtis Michie <[email protected]>
AuthorDate: Fri Dec 16 10:09:51 2022 -0700
Tpv2/regions (#7243)
* Pluralized division-detail file names to fix disparity from
divisons-table file names
* Added mocha dependency back
* Created Regions Detail and Regions Table UI pages with tests. Updated
necessary ts classes to support new pages.
Reverted naming convention for division. Should be singular because this
pertains to individual divisions.
* Created testing classes for regions page
* Created Nightwatch tests for regions page and changed plural name to
singular for divisionDetail.ts
* Updated Divisions column to display division name
* Updated nightwatch test filepath names in globals.ts
* Added mocha dependency into package json files
* Fixed failing test for region-detail.component.spec.ts
* Removed Mocha dependency
* Corrects mismatched divisions and regions vs division and region pages
* Updated description for accuracy
* Formatted imports
* Fixed delete functionality for region and division. Corrected typing on
FormControl. Added divisions navigation into regions and placeholder for
physical locations.
* Corrected View Regions on divisions-table.component.ts ot be a link to
the regions of the selected division. Changed Link for navigation to not be a
click handler, and be a href function for View Divisions on
divisions-table.component.ts
* Amending attempt to View filtered regions per Division. Will need deeper
work to operate as intended.
---
.../traffic-portal/nightwatch/globals/globals.ts | 24 ++++++-
.../nightwatch/page_objects/regionDetail.ts | 43 +++++++++++
.../nightwatch/page_objects/regionsTable.ts | 46 ++++++++++++
.../tests/cacheGroups/divisions/detail.spec.ts | 4 +-
.../{divisions => regions}/detail.spec.ts | 20 +++---
.../tests/cacheGroups/regions/table.spec.ts | 24 +++++++
experimental/traffic-portal/package-lock.json | 14 ++--
experimental/traffic-portal/package.json | 2 +-
.../src/app/api/cache-group.service.ts | 74 ++++++++++++++++++-
.../src/app/api/testing/cache-group.service.ts | 83 +++++++++++++++++++++-
.../divisions/detail/division-detail.component.ts | 2 +-
.../divisions/table/divisions-table.component.ts | 10 +--
.../regions/detail/region-detail.component.html | 42 +++++++++++
.../regions/detail/region-detail.component.scss | 25 +++++++
.../regions/detail/region-detail.component.spec.ts | 77 ++++++++++++++++++++
.../detail/region-detail.component.ts} | 48 +++++++------
.../regions/table/regions-table.component.html | 30 ++++++++
.../regions/table/regions-table.component.scss | 14 ++++
.../regions/table/regions-table.component.spec.ts | 81 +++++++++++++++++++++
.../table/regions-table.component.ts} | 54 ++++++++------
.../traffic-portal/src/app/core/core.module.ts | 10 ++-
21 files changed, 652 insertions(+), 75 deletions(-)
diff --git a/experimental/traffic-portal/nightwatch/globals/globals.ts
b/experimental/traffic-portal/nightwatch/globals/globals.ts
index 45845b7aa0..bed3a84b8c 100644
--- a/experimental/traffic-portal/nightwatch/globals/globals.ts
+++ b/experimental/traffic-portal/nightwatch/globals/globals.ts
@@ -24,6 +24,8 @@ import type {DeliveryServiceInvalidPageObject} from
"nightwatch/page_objects/del
import type { DivisionDetailPageObject } from
"nightwatch/page_objects/divisionDetail";
import type { DivisionsPageObject } from
"nightwatch/page_objects/divisionsTable";
import type {LoginPageObject} from "nightwatch/page_objects/login";
+import type { RegionDetailPageObject } from
"nightwatch/page_objects/regionDetail";
+import type { RegionsPageObject } from "nightwatch/page_objects/regionsTable";
import type {ServersPageObject} from "nightwatch/page_objects/servers";
import type { TenantDetailPageObject } from
"nightwatch/page_objects/tenantDetail";
import type { TenantsPageObject } from "nightwatch/page_objects/tenants";
@@ -36,7 +38,13 @@ import {
ResponseCDN,
ResponseDeliveryService,
RequestTenant,
- ResponseTenant, TypeFromResponse, RequestSteeringTarget,
ResponseDivision, RequestDivision
+ ResponseTenant,
+ TypeFromResponse,
+ RequestSteeringTarget,
+ ResponseDivision,
+ RequestDivision,
+ ResponseRegion,
+ RequestRegion
} from "trafficops-types";
declare module "nightwatch" {
@@ -49,9 +57,11 @@ declare module "nightwatch" {
deliveryServiceCard: () => DeliveryServiceCardPageObject;
deliveryServiceDetail: () => DeliveryServiceDetailPageObject;
deliveryServiceInvalidationJobs: () =>
DeliveryServiceInvalidPageObject;
- divisionsDetail: () => DivisionDetailPageObject;
+ divisionDetail: () => DivisionDetailPageObject;
divisionsTable: () => DivisionsPageObject;
login: () => LoginPageObject;
+ regionDetail: () => RegionDetailPageObject;
+ regionsTable: () => RegionsPageObject;
servers: () => ServersPageObject;
tenants: () => TenantsPageObject;
tenantDetail: () => TenantDetailPageObject;
@@ -81,6 +91,7 @@ export interface CreatedData {
steeringDS: ResponseDeliveryService;
tenant: ResponseTenant;
division: ResponseDivision;
+ region: ResponseRegion;
}
const testData = {};
@@ -235,6 +246,15 @@ const globals = {
const respDivision: ResponseDivision =
resp.data.response;
console.log(`Successfully created Division
${respDivision.name}`);
data.division = respDivision;
+
+ const region: RequestRegion = {
+ division: 1,
+ name: `testR${globals.uniqueString}`
+ };
+ resp = await client.post(`${apiUrl}/regions`,
JSON.stringify(region));
+ const respRegion: ResponseRegion = resp.data.response;
+ console.log(`Successfully created Region
${respRegion.name}`);
+ data.region = respRegion;
} catch(e) {
console.error((e as AxiosError).message);
throw e;
diff --git
a/experimental/traffic-portal/nightwatch/page_objects/regionDetail.ts
b/experimental/traffic-portal/nightwatch/page_objects/regionDetail.ts
new file mode 100644
index 0000000000..3f2d6b4de6
--- /dev/null
+++ b/experimental/traffic-portal/nightwatch/page_objects/regionDetail.ts
@@ -0,0 +1,43 @@
+/*
+ * 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 { EnhancedPageObject } from "nightwatch";
+
+/**
+ * Defines the PageObject for Region Details.
+ */
+export type RegionDetailPageObject = EnhancedPageObject<{}, typeof
regionDetailPageObject.elements>;
+
+const regionDetailPageObject = {
+ elements: {
+ division: {
+ selector: "mat-select[name='division']"
+ },
+ id: {
+ selector: "input[name='id']"
+ },
+ lastUpdated: {
+ selector: "input[name='lastUpdated']"
+ },
+ name: {
+ selector: "input[name='name']"
+ },
+
+ saveBtn: {
+ selector: "button[type='submit']"
+ }
+ },
+};
+
+export default regionDetailPageObject;
diff --git
a/experimental/traffic-portal/nightwatch/page_objects/regionsTable.ts
b/experimental/traffic-portal/nightwatch/page_objects/regionsTable.ts
new file mode 100644
index 0000000000..a2777662a8
--- /dev/null
+++ b/experimental/traffic-portal/nightwatch/page_objects/regionsTable.ts
@@ -0,0 +1,46 @@
+/*
+ * 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 { EnhancedPageObject, EnhancedSectionInstance, NightwatchAPI } from
"nightwatch";
+
+import { TABLE_COMMANDS, TableSectionCommands } from "../globals/tables";
+
+/**
+ * Defines the Regions table commands
+ */
+type RegionsTableCommands = TableSectionCommands;
+
+/**
+ * Defines the Page Object for the Regions page.
+ */
+export type RegionsPageObject = EnhancedPageObject<{}, {},
+EnhancedSectionInstance<RegionsTableCommands>>;
+
+const regionsPageObject = {
+ api: {} as NightwatchAPI,
+ sections: {
+ regionsTable: {
+ commands: {
+ ...TABLE_COMMANDS
+ },
+ elements: {},
+ selector: "mat-card"
+ }
+ },
+ url(): string {
+ return `${this.api.launchUrl}/core/regions`;
+ }
+};
+
+export default regionsPageObject;
diff --git
a/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
index 96b0a59a90..943ed77176 100644
---
a/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
+++
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
@@ -15,7 +15,7 @@
describe("Division Detail Spec", () => {
it("Test division", () => {
const page = browser.page.divisionDetail();
-
browser.url(`${page.api.launchUrl}/core/divisions/${browser.globals.testData.division.id}`,
res => {
+
browser.url(`${page.api.launchUrl}/core/division/${browser.globals.testData.division.id}`,
res => {
browser.assert.ok(res.status === 0);
page.waitForElementVisible("mat-card")
.assert.enabled("@name")
@@ -29,7 +29,7 @@ describe("Division Detail Spec", () => {
it("New division", () => {
const page = browser.page.divisionDetail();
- browser.url(`${page.api.launchUrl}/core/divisions/new`, res => {
+ browser.url(`${page.api.launchUrl}/core/division/new`, res => {
browser.assert.ok(res.status === 0);
page.waitForElementVisible("mat-card")
.assert.enabled("@name")
diff --git
a/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/detail.spec.ts
similarity index 65%
copy from
experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
copy to
experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/detail.spec.ts
index 96b0a59a90..8af0540622 100644
---
a/experimental/traffic-portal/nightwatch/tests/cacheGroups/divisions/detail.spec.ts
+++
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/detail.spec.ts
@@ -12,27 +12,29 @@
* limitations under the License.
*/
-describe("Division Detail Spec", () => {
- it("Test division", () => {
- const page = browser.page.divisionDetail();
-
browser.url(`${page.api.launchUrl}/core/divisions/${browser.globals.testData.division.id}`,
res => {
+describe("Region Detail Spec", () => {
+ it("Test region", () => {
+ const page = browser.page.regionDetail();
+
browser.url(`${page.api.launchUrl}/core/region/${browser.globals.testData.region.id}`,
res => {
browser.assert.ok(res.status === 0);
page.waitForElementVisible("mat-card")
.assert.enabled("@name")
+ .assert.enabled("@division")
.assert.enabled("@saveBtn")
.assert.not.enabled("@id")
.assert.not.enabled("@lastUpdated")
- .assert.valueEquals("@name",
browser.globals.testData.division.name)
- .assert.valueEquals("@id",
String(browser.globals.testData.division.id));
+ .assert.valueEquals("@name",
browser.globals.testData.region.name)
+ .assert.valueEquals("@id",
String(browser.globals.testData.region.id));
});
});
- it("New division", () => {
- const page = browser.page.divisionDetail();
- browser.url(`${page.api.launchUrl}/core/divisions/new`, res => {
+ it("New region", () => {
+ const page = browser.page.regionDetail();
+ browser.url(`${page.api.launchUrl}/core/region/new`, res => {
browser.assert.ok(res.status === 0);
page.waitForElementVisible("mat-card")
.assert.enabled("@name")
+ .assert.enabled("@division")
.assert.enabled("@saveBtn")
.assert.not.elementPresent("@id")
.assert.not.elementPresent("@lastUpdated")
diff --git
a/experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/table.spec.ts
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/table.spec.ts
new file mode 100644
index 0000000000..780c85c5ff
--- /dev/null
+++
b/experimental/traffic-portal/nightwatch/tests/cacheGroups/regions/table.spec.ts
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+describe("Regions Spec", () => {
+ it("Loads elements", async () => {
+ browser.page.regionsTable().navigate()
+ .waitForElementPresent("input[name=fuzzControl]");
+ browser.elements("css selector", "div.ag-row", rows => {
+ browser.assert.ok(rows.status === 0);
+ browser.assert.ok((rows.value as []).length >= 3);
+ });
+ });
+});
diff --git a/experimental/traffic-portal/package-lock.json
b/experimental/traffic-portal/package-lock.json
index b9f3a88759..42dc94c56b 100644
--- a/experimental/traffic-portal/package-lock.json
+++ b/experimental/traffic-portal/package-lock.json
@@ -54,7 +54,7 @@
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"axios": "^0.27.2",
- "chromedriver": "^107.0.3",
+ "chromedriver": "^108.0.0",
"codelyzer": "^6.0.0",
"eslint": "^8.23.0",
"eslint-plugin-import": "^2.25.3",
@@ -6083,9 +6083,9 @@
}
},
"node_modules/chromedriver": {
- "version": "107.0.3",
- "resolved":
"https://registry.npmjs.org/chromedriver/-/chromedriver-107.0.3.tgz",
- "integrity":
"sha512-jmzpZgctCRnhYAn0l/NIjP4vYN3L8GFVbterTrRr2Ly3W5rFMb9H8EKGuM5JCViPKSit8FbE718kZTEt3Yvffg==",
+ "version": "108.0.0",
+ "resolved":
"https://registry.npmjs.org/chromedriver/-/chromedriver-108.0.0.tgz",
+ "integrity":
"sha512-/kb0rb0dlC4RfXh2BOT7RV87K6d+It3VV5YXebLzO5a8t2knNffiTE23XPJQCH+l1xmgoW8/sOX/NB9irskvOQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -22882,9 +22882,9 @@
"dev": true
},
"chromedriver": {
- "version": "107.0.3",
- "resolved":
"https://registry.npmjs.org/chromedriver/-/chromedriver-107.0.3.tgz",
- "integrity":
"sha512-jmzpZgctCRnhYAn0l/NIjP4vYN3L8GFVbterTrRr2Ly3W5rFMb9H8EKGuM5JCViPKSit8FbE718kZTEt3Yvffg==",
+ "version": "108.0.0",
+ "resolved":
"https://registry.npmjs.org/chromedriver/-/chromedriver-108.0.0.tgz",
+ "integrity":
"sha512-/kb0rb0dlC4RfXh2BOT7RV87K6d+It3VV5YXebLzO5a8t2knNffiTE23XPJQCH+l1xmgoW8/sOX/NB9irskvOQ==",
"dev": true,
"requires": {
"@testim/chrome-version": "^1.1.3",
diff --git a/experimental/traffic-portal/package.json
b/experimental/traffic-portal/package.json
index 44d8f85a60..0fe29a3d7f 100644
--- a/experimental/traffic-portal/package.json
+++ b/experimental/traffic-portal/package.json
@@ -94,7 +94,7 @@
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"axios": "^0.27.2",
- "chromedriver": "^107.0.3",
+ "chromedriver": "^108.0.0",
"codelyzer": "^6.0.0",
"eslint": "^8.23.0",
"eslint-plugin-import": "^2.25.3",
diff --git a/experimental/traffic-portal/src/app/api/cache-group.service.ts
b/experimental/traffic-portal/src/app/api/cache-group.service.ts
index cde7cacfe5..7fab81817a 100644
--- a/experimental/traffic-portal/src/app/api/cache-group.service.ts
+++ b/experimental/traffic-portal/src/app/api/cache-group.service.ts
@@ -13,7 +13,7 @@
*/
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
-import type { RequestDivision, ResponseDivision } from "trafficops-types";
+import type { RequestDivision, ResponseDivision, RequestRegion, ResponseRegion
} from "trafficops-types";
import type { CacheGroup } from "src/app/models";
@@ -162,6 +162,78 @@ export class CacheGroupService extends APIService {
return
this.delete<ResponseDivision>(`divisions/${id}`).toPromise();
}
+ public async getRegions(): Promise<Array<ResponseRegion>>;
+ public async getRegions(nameOrID: string | number):
Promise<ResponseRegion>;
+
+ /**
+ * Gets an array of regions from Traffic Ops.
+ *
+ * @param nameOrID If given, returns only the Region with the given name
+ * (string) or ID (number).
+ * @returns An Array of Region objects - or a single Region object if
'nameOrID'
+ * was given.
+ */
+ public async getRegions(nameOrID?: string | number):
Promise<Array<ResponseRegion> | ResponseRegion> {
+ const path = "regions";
+ if(nameOrID) {
+ let params;
+ switch (typeof nameOrID) {
+ case "string":
+ params = {name: nameOrID};
+ break;
+ case "number":
+ params = {id: String(nameOrID)};
+ }
+ const r = await this.get<[ResponseRegion]>(path,
undefined, params).toPromise();
+ return {...r[0], lastUpdated: new
Date((r[0].lastUpdated as unknown as string).replace("+00", "Z"))};
+
+ }
+ const regions = await
this.get<Array<ResponseRegion>>(path).toPromise();
+ return regions.map(
+ d => ({...d, lastUpdated: new Date((d.lastUpdated as
unknown as string).replace("+00", "Z"))})
+ );
+ }
+
+ /**
+ * Replaces the current definition of a region with the one given.
+ *
+ * @param region The new region.
+ * @returns The updated region.
+ */
+ public async updateRegion(region: ResponseRegion):
Promise<ResponseRegion> {
+ const path = `regions/${region.id}`;
+ const response = await this.put<ResponseRegion>(path,
region).toPromise();
+ return {
+ ...response,
+ lastUpdated: new Date((response.lastUpdated as unknown
as string).replace(" ", "T").replace("+00", "Z"))
+ };
+ }
+
+ /**
+ * Creates a new region.
+ *
+ * @param region The region to create.
+ * @returns The created region.
+ */
+ public async createRegion(region: RequestRegion):
Promise<ResponseRegion> {
+ const response = await this.post<ResponseRegion>("regions",
region).toPromise();
+ return {
+ ...response,
+ lastUpdated: new Date((response.lastUpdated as unknown
as string).replace(" ", "T").replace("+00", "Z"))
+ };
+ }
+
+ /**
+ * Deletes an existing region.
+ *
+ * @param regionOrId Id of the region to delete.
+ * @returns The deleted region.
+ */
+ public async deleteRegion(regionOrId: number | ResponseRegion):
Promise<void> {
+ const id = typeof(regionOrId) === "number" ? regionOrId :
regionOrId.id;
+ await this.delete("regions/", undefined, { id : String(id)
}).toPromise();
+ }
+
constructor(http: HttpClient) {
super(http);
}
diff --git
a/experimental/traffic-portal/src/app/api/testing/cache-group.service.ts
b/experimental/traffic-portal/src/app/api/testing/cache-group.service.ts
index 20057bde94..99f5f2c8ed 100644
--- a/experimental/traffic-portal/src/app/api/testing/cache-group.service.ts
+++ b/experimental/traffic-portal/src/app/api/testing/cache-group.service.ts
@@ -12,7 +12,7 @@
* limitations under the License.
*/
import { Injectable } from "@angular/core";
-import { RequestDivision, ResponseDivision } from "trafficops-types";
+import { RequestDivision, ResponseDivision, RequestRegion, ResponseRegion }
from "trafficops-types";
import type { CacheGroup } from "src/app/models";
@@ -29,6 +29,14 @@ export class CacheGroupService {
name: "Div1"
}
];
+ private readonly regions: Array<ResponseRegion> = [{
+ division: 1,
+ divisionName: "div1",
+ id: 1,
+ lastUpdated: new Date(),
+ name: "Reg1"
+ }
+ ];
private readonly cacheGroups = [
{
fallbackToClosest: true,
@@ -195,4 +203,77 @@ export class CacheGroupService {
}
return this.divisions.splice(index, 1)[0];
}
+
+ public async getRegions(): Promise<Array<ResponseRegion>>;
+ public async getRegions(nameOrID: string | number):
Promise<ResponseRegion>;
+
+ /**
+ * Gets an array of regions from Traffic Ops.
+ *
+ * @param nameOrID If given, returns only the ResponseRegion with the
given name
+ * (string) or ID (number).
+ * @returns An Array of ResponseRegion objects - or a single
ResponseRegion object if 'nameOrID'
+ * was given.
+ */
+ public async getRegions(nameOrID?: string | number):
Promise<Array<ResponseRegion> | ResponseRegion> {
+ if(nameOrID) {
+ let region;
+ switch (typeof nameOrID) {
+ case "string":
+ region = this.regions.find(d=>d.name
=== nameOrID);
+ break;
+ case "number":
+ region = this.regions.find(d=>d.id ===
nameOrID);
+ }
+ if (!region) {
+ throw new Error(`no such Region: ${nameOrID}`);
+ }
+ return region;
+ }
+ return this.regions;
+ }
+
+ /**
+ * Replaces the current definition of a region with the one given.
+ *
+ * @param region The new region.
+ * @returns The updated region.
+ */
+ public async updateRegion(region: ResponseRegion):
Promise<ResponseRegion> {
+ const id = this.regions.findIndex(d => d.id === region.id);
+ if (id === -1) {
+ throw new Error(`no such Region: ${region.id}`);
+ }
+ this.regions[id] = region;
+ return region;
+ }
+
+ /**
+ * Creates a new region.
+ *
+ * @param region The region to create.
+ * @returns The created region.
+ */
+ public async createRegion(region: RequestRegion):
Promise<ResponseRegion> {
+ return {
+ divisionName: "Div1",
+ ...region,
+ id: ++this.lastID,
+ lastUpdated: new Date()
+ };
+ }
+
+ /**
+ * Deletes an existing region.
+ *
+ * @param id Id of the region to delete.
+ * @returns The deleted region.
+ */
+ public async deleteRegion(id: number): Promise<ResponseRegion> {
+ const index = this.regions.findIndex(d => d.id === id);
+ if (index === -1) {
+ throw new Error(`no such Region: ${id}`);
+ }
+ return this.regions.splice(index, 1)[0];
+ }
}
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
b/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
index cce2176fef..424f11f9df 100644
---
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
+++
b/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
@@ -89,7 +89,7 @@ export class DivisionDetailComponent implements OnInit {
/**
* Submits new/updated division.
*
- * @param e HTML click event.
+ * @param e HTML form submission event.
*/
public async submit(e: Event): Promise<void> {
e.preventDefault();
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
b/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
index 3178c1d0f5..4532a185ff 100644
---
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
+++
b/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
@@ -35,7 +35,7 @@ import { TpHeaderService } from
"src/app/shared/tp-header/tp-header.service";
})
export class DivisionsTableComponent implements OnInit {
/** List of divisions */
- public readonly divisions: Promise<Array<ResponseDivision>>;
+ public divisions: Promise<Array<ResponseDivision>>;
constructor(private readonly route: ActivatedRoute, private readonly
headerSvc: TpHeaderService, private readonly router: Router,
private readonly api: CacheGroupService, private readonly
dialog: MatDialog, public readonly auth: CurrentUserService) {
@@ -100,11 +100,11 @@ export class DivisionsTableComponent implements OnInit {
public fuzzySubject: BehaviorSubject<string>;
/** Form controller for the user search input. */
- public fuzzControl: FormControl = new FormControl<string>("");
+ public fuzzControl = new FormControl<string>("");
/** Update the URL's 'search' query parameter for the user's search
input. */
public updateURL(): void {
- this.fuzzySubject.next(this.fuzzControl.value);
+ this.fuzzySubject.next(this.fuzzControl.value ?? "");
}
/**
@@ -121,12 +121,12 @@ export class DivisionsTableComponent implements OnInit {
});
ref.afterClosed().subscribe(result => {
if(result) {
-
this.api.deleteDivision(data.id);
+
this.api.deleteDivision(data.id).then(async () => this.divisions =
this.api.getDivisions());
}
});
break;
case "edit":
- await this.router.navigate(["/core/divisions",
data.id]);
+ await this.router.navigate(["/core/division",
data.id]);
break;
case "viewRegions":
console.log("Regions not implemented");
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.html
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.html
new file mode 100644
index 0000000000..9e80094c2d
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.html
@@ -0,0 +1,42 @@
+<!--
+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.
+-->
+
+<mat-card>
+ <tp-loading *ngIf="!region"></tp-loading>
+ <form ngNativeValidate (ngSubmit)="submit($event)" *ngIf="region">
+ <mat-card-content>
+ <mat-form-field>
+ <mat-label>Name</mat-label>
+ <input matInput type="text" name="name"
required [(ngModel)]="region.name" />
+ </mat-form-field>
+ <mat-form-field>
+ <mat-label>Division</mat-label>
+ <mat-select
name="division"[(ngModel)]="region.division" required>
+ <mat-option *ngFor="let
division of divisions" [value]="division.id">{{division.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ <mat-form-field *ngIf="!new">
+ <mat-label>ID</mat-label>
+ <input matInput type="text" name="id" disabled
readonly [defaultValue]="region.id" />
+ </mat-form-field>
+ <mat-form-field *ngIf="!new">
+ <mat-label>Last Updated</mat-label>
+ <input matInput type="text" name="lastUpdated"
disabled readonly [defaultValue]="region.lastUpdated" /> </mat-form-field>
+ </mat-card-content>
+ <mat-card-actions align="end">
+ <button mat-raised-button type="button" *ngIf="!new"
color="warn" (click)="deleteRegion()">Delete</button>
+ <button mat-raised-button type="submit"
color="primary">Save</button>
+ </mat-card-actions>
+ </form>
+</mat-card>
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.scss
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.scss
new file mode 100644
index 0000000000..f4746e2a22
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.scss
@@ -0,0 +1,25 @@
+/*
+* 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.
+*/
+mat-card {
+ margin: 1em auto;
+ width: 80%;
+ min-width: 350px;
+
+ mat-card-content {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-row-gap: 2em;
+ margin: 1em auto 50px;
+ }
+}
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.spec.ts
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.spec.ts
new file mode 100644
index 0000000000..d107b5a8a9
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.spec.ts
@@ -0,0 +1,77 @@
+/*
+* 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 { RegionDetailComponent } from
"src/app/core/cache-groups/regions/detail/region-detail.component";
+import { TpHeaderService } from "src/app/shared/tp-header/tp-header.service";
+
+describe("DetailComponent", () => {
+ let component: RegionDetailComponent;
+ let fixture: ComponentFixture<RegionDetailComponent>;
+ let route: ActivatedRoute;
+ let paramMap: jasmine.Spy;
+
+ const headerSvc = jasmine.createSpyObj([],{headerHidden: new
ReplaySubject<boolean>(), headerTitle: new ReplaySubject<string>()});
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ RegionDetailComponent ],
+ imports: [ APITestingModule, RouterTestingModule,
MatDialogModule ],
+ providers: [ { provide: TpHeaderService, useValue:
headerSvc } ]
+ })
+ .compileComponents();
+
+ route = TestBed.inject(ActivatedRoute);
+ paramMap = spyOn(route.snapshot.paramMap, "get");
+ paramMap.and.returnValue(null);
+ fixture = TestBed.createComponent(RegionDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ expect(paramMap).toHaveBeenCalled();
+ });
+
+ it("new region", async () => {
+ paramMap.and.returnValue("new");
+
+ fixture = TestBed.createComponent(RegionDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ await fixture.whenStable();
+ expect(paramMap).toHaveBeenCalled();
+ expect(component.region).not.toBeNull();
+ expect(component.region.name).toBe("");
+ expect(component.new).toBeTrue();
+ });
+
+ it("existing region", async () => {
+ paramMap.and.returnValue("1");
+
+ fixture = TestBed.createComponent(RegionDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ await fixture.whenStable();
+ expect(paramMap).toHaveBeenCalled();
+ expect(component.region).not.toBeNull();
+ expect(component.region.name).toBe("Reg1");
+ expect(component.new).toBeFalse();
+ });
+});
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.ts
similarity index 62%
copy from
experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
copy to
experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.ts
index cce2176fef..515185a00f 100644
---
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/detail/division-detail.component.ts
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/detail/region-detail.component.ts
@@ -15,31 +15,35 @@ import { Location } from "@angular/common";
import { Component, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute } from "@angular/router";
-import { ResponseDivision } from "trafficops-types";
+import { ResponseDivision, ResponseRegion } from "trafficops-types";
import { CacheGroupService } from "src/app/api";
import { DecisionDialogComponent } from
"src/app/shared/dialogs/decision-dialog/decision-dialog.component";
import { TpHeaderService } from "src/app/shared/tp-header/tp-header.service";
/**
- * DivisionDetailsComponent is the controller for the division add/edit form.
+ * RegionDetailsComponent is the controller for the region add/edit form.
*/
@Component({
- selector: "tp-divisions-detail",
- styleUrls: ["./division-detail.component.scss"],
- templateUrl: "./division-detail.component.html"
+ selector: "tp-regions-detail",
+ styleUrls: ["./region-detail.component.scss"],
+ templateUrl: "./region-detail.component.html"
})
-export class DivisionDetailComponent implements OnInit {
+export class RegionDetailComponent implements OnInit {
public new = false;
- public division!: ResponseDivision;
+ public region!: ResponseRegion;
+ public divisions!: Array<ResponseDivision>;
constructor(private readonly route: ActivatedRoute, private readonly
cacheGroupService: CacheGroupService,
- private readonly location: Location, private readonly dialog:
MatDialog, private readonly header: TpHeaderService) { }
+ private readonly location: Location, private readonly dialog:
MatDialog,
+ private readonly header: TpHeaderService) {
+ }
/**
* Angular lifecycle hook where data is initialized.
*/
public async ngOnInit(): Promise<void> {
+ this.divisions = await this.cacheGroupService.getDivisions();
const ID = this.route.snapshot.paramMap.get("id");
if (ID === null) {
console.error("missing required route parameter 'id'");
@@ -47,9 +51,11 @@ export class DivisionDetailComponent implements OnInit {
}
if (ID === "new") {
- this.header.headerTitle.next("New Division");
+ this.header.headerTitle.next("New Region");
this.new = true;
- this.division = {
+ this.region = {
+ division: -1,
+ divisionName: "",
id: -1,
lastUpdated: new Date(),
name: ""
@@ -62,43 +68,43 @@ export class DivisionDetailComponent implements OnInit {
return;
}
- this.division = await
this.cacheGroupService.getDivisions(numID);
- this.header.headerTitle.next(`Division: ${this.division.name}`);
+ this.region = await this.cacheGroupService.getRegions(numID);
+ this.header.headerTitle.next(`Region: ${this.region.name}`);
}
/**
- * Deletes the current division.
+ * Deletes the current region.
*/
- public async deleteDivision(): Promise<void> {
+ public async deleteRegion(): Promise<void> {
if (this.new) {
- console.error("Unable to delete new division");
+ console.error("Unable to delete new region");
return;
}
const ref = this.dialog.open(DecisionDialogComponent, {
- data: {message: `Are you sure you want to delete
division ${this.division.name} with id ${this.division.id}`,
+ data: {message: `Are you sure you want to delete region
${this.region.name} with id ${this.region.id}`,
title: "Confirm Delete"}
});
ref.afterClosed().subscribe(result => {
if(result) {
-
this.cacheGroupService.deleteDivision(this.division.id);
+
this.cacheGroupService.deleteRegion(this.region.id);
this.location.back();
}
});
}
/**
- * Submits new/updated division.
+ * Submits new/updated region.
*
- * @param e HTML click event.
+ * @param e HTML form submission event.
*/
public async submit(e: Event): Promise<void> {
e.preventDefault();
e.stopPropagation();
if(this.new) {
- this.division = await
this.cacheGroupService.createDivision(this.division);
+ this.region = await
this.cacheGroupService.createRegion(this.region);
this.new = false;
} else {
- this.division = await
this.cacheGroupService.updateDivision(this.division);
+ this.region = await
this.cacheGroupService.updateRegion(this.region);
}
}
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.html
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.html
new file mode 100644
index 0000000000..72c876dbea
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.html
@@ -0,0 +1,30 @@
+<!--
+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.
+-->
+
+<mat-card class="table-page-content">
+ <div class="search-container">
+ <input type="search" name="fuzzControl" aria-label="Fuzzy
Search Regions" autofocus inputmode="search" role="search" accesskey="/"
placeholder="Fuzzy Search" [formControl]="fuzzControl" (input)="updateURL()" />
+ </div>
+ <tp-generic-table
+ [data]="regions | async"
+ [cols]="columnDefs"
+ [fuzzySearch]="fuzzySubject"
+ context="regions"
+ [contextMenuItems]="contextMenuItems"
+ (contextMenuAction)="handleContextMenu($event)">
+ </tp-generic-table>
+</mat-card>
+
+
+<button class="page-fab" mat-fab title="Create a new Region"
*ngIf="auth.hasPermission('REGION:CREATE')"
routerLink="new"><mat-icon>add</mat-icon></button>
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.scss
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.scss
new file mode 100644
index 0000000000..a76ede4a23
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.scss
@@ -0,0 +1,14 @@
+/*
+* 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.
+*/
+
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.spec.ts
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.spec.ts
new file mode 100644
index 0000000000..added1e0e8
--- /dev/null
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.spec.ts
@@ -0,0 +1,81 @@
+/*
+* 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, fakeAsync, TestBed, tick } from
"@angular/core/testing";
+import { MatDialogModule } from "@angular/material/dialog";
+import { RouterTestingModule } from "@angular/router/testing";
+import { BehaviorSubject } from "rxjs";
+
+import { APITestingModule } from "src/app/api/testing";
+import { DivisionsTableComponent } from
"src/app/core/cache-groups/divisions/table/divisions-table.component";
+import { CurrentUserService } from
"src/app/shared/currentUser/current-user.service";
+
+describe("DivisionsTableComponent", () => {
+ let component: DivisionsTableComponent;
+ let fixture: ComponentFixture<DivisionsTableComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ DivisionsTableComponent ],
+ imports: [ APITestingModule, RouterTestingModule,
MatDialogModule ],
+ providers: [
+ {
+ provide: CurrentUserService,
+ useValue: {
+ currentUser: {
+ },
+ hasPermission: (): true => true,
+ userChanged: new
BehaviorSubject({})
+ }
+ }
+ ]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(DivisionsTableComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+
+ it("updates the fuzzy search output", fakeAsync(() => {
+ let called = false;
+ const text = "testquest";
+ const spy = jasmine.createSpy("subscriber", (txt: string): void
=>{
+ if (!called) {
+ expect(txt).toBe("");
+ called = true;
+ } else {
+ expect(txt).toBe(text);
+ }
+ });
+ component.fuzzySubject.subscribe(spy);
+ tick();
+ expect(spy).toHaveBeenCalled();
+ component.fuzzControl.setValue(text);
+ component.updateURL();
+ tick();
+ expect(spy).toHaveBeenCalledTimes(2);
+ }));
+
+ it("handles contextmenu events", () => {
+ expect(async () => component.handleContextMenu({
+ action: component.contextMenuItems[0].name,
+ data: {id: 1, lastUpdated: new Date(), name: "Div"}
+ })).not.toThrow();
+ });
+});
diff --git
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.ts
similarity index 70%
copy from
experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
copy to
experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.ts
index 3178c1d0f5..d3cb0b266b 100644
---
a/experimental/traffic-portal/src/app/core/cache-groups/divisions/table/divisions-table.component.ts
+++
b/experimental/traffic-portal/src/app/core/cache-groups/regions/table/regions-table.component.ts
@@ -17,7 +17,7 @@ import { FormControl } from "@angular/forms";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute, Router } from "@angular/router";
import { BehaviorSubject } from "rxjs";
-import { Division, ResponseDivision } from "trafficops-types";
+import { Region, ResponseRegion } from "trafficops-types";
import { CacheGroupService } from "src/app/api";
import { CurrentUserService } from
"src/app/shared/currentUser/current-user.service";
@@ -26,21 +26,21 @@ import { ContextMenuActionEvent, ContextMenuItem } from
"src/app/shared/generic-
import { TpHeaderService } from "src/app/shared/tp-header/tp-header.service";
/**
- * DivisionsTableComponent is the controller for the "Divisions" table.
+ * RegionsTableComponent is the controller for the "Regions" table.
*/
@Component({
- selector: "tp-divisions",
- styleUrls: ["./divisions-table.component.scss"],
- templateUrl: "./divisions-table.component.html"
+ selector: "tp-regions",
+ styleUrls: ["./regions-table.component.scss"],
+ templateUrl: "./regions-table.component.html"
})
-export class DivisionsTableComponent implements OnInit {
- /** List of divisions */
- public readonly divisions: Promise<Array<ResponseDivision>>;
+export class RegionsTableComponent implements OnInit {
+ /** List of regions */
+ public regions: Promise<Array<ResponseRegion>>;
constructor(private readonly route: ActivatedRoute, private readonly
headerSvc: TpHeaderService, private readonly router: Router,
private readonly api: CacheGroupService, private readonly
dialog: MatDialog, public readonly auth: CurrentUserService) {
this.fuzzySubject = new BehaviorSubject<string>("");
- this.divisions = this.api.getDivisions();
+ this.regions = this.api.getRegions();
}
/** Initializes table data, loading it from Traffic Ops. */
@@ -57,7 +57,7 @@ export class DivisionsTableComponent implements OnInit {
console.error("Failed to get query
parameters:", e);
}
);
- this.headerSvc.headerTitle.next("Divisions");
+ this.headerSvc.headerTitle.next("Regions");
}
/** Definitions of the table's columns according to the ag-grid API */
@@ -66,6 +66,10 @@ export class DivisionsTableComponent implements OnInit {
field: "name",
headerName: "Name"
},
+ {
+ field: "divisionName",
+ headerName: "Division"
+ },
{
field: "id",
headerName:" ID",
@@ -77,8 +81,8 @@ export class DivisionsTableComponent implements OnInit {
}
];
- /** Definitions for the context menu items (which act on augmented
division data). */
- public contextMenuItems: Array<ContextMenuItem<Division>> = [
+ /** Definitions for the context menu items (which act on augmented
region data). */
+ public contextMenuItems: Array<ContextMenuItem<Region>> = [
{
action: "edit",
multiRow: false,
@@ -90,9 +94,13 @@ export class DivisionsTableComponent implements OnInit {
name: "Delete"
},
{
- action: "viewRegions",
+ href: (selectedRow: Region): string =>
`/core/division/${selectedRow.division}`,
+ name: "View Division"
+ },
+ {
+ action: "viewPhysLocs",
multiRow: false,
- name: "View Regions"
+ name: "View Physical Locations"
}
];
@@ -100,11 +108,11 @@ export class DivisionsTableComponent implements OnInit {
public fuzzySubject: BehaviorSubject<string>;
/** Form controller for the user search input. */
- public fuzzControl: FormControl = new FormControl<string>("");
+ public fuzzControl = new FormControl<string>("");
/** Update the URL's 'search' query parameter for the user's search
input. */
public updateURL(): void {
- this.fuzzySubject.next(this.fuzzControl.value);
+ this.fuzzySubject.next(this.fuzzControl.value ?? "");
}
/**
@@ -112,24 +120,24 @@ export class DivisionsTableComponent implements OnInit {
*
* @param evt The action selected from the context menu.
*/
- public async handleContextMenu(evt:
ContextMenuActionEvent<ResponseDivision>): Promise<void> {
- const data = evt.data as ResponseDivision;
+ public async handleContextMenu(evt:
ContextMenuActionEvent<ResponseRegion>): Promise<void> {
+ const data = evt.data as ResponseRegion;
switch(evt.action) {
case "delete":
const ref =
this.dialog.open(DecisionDialogComponent, {
- data: {message: `Are you sure you want
to delete division ${data.name} with id ${data.id}`, title: "Confirm Delete"}
+ data: {message: `Are you sure you want
to delete region ${data.name} with id ${data.id}`, title: "Confirm Delete"}
});
ref.afterClosed().subscribe(result => {
if(result) {
-
this.api.deleteDivision(data.id);
+
this.api.deleteRegion(data.id).then(async () => this.regions =
this.api.getRegions());
}
});
break;
case "edit":
- await this.router.navigate(["/core/divisions",
data.id]);
+ await this.router.navigate(["/core/region",
data.id]);
break;
- case "viewRegions":
- console.log("Regions not implemented");
+ case "viewPhysLocs":
+ console.log("Physical Locations not
implemented");
}
}
}
diff --git a/experimental/traffic-portal/src/app/core/core.module.ts
b/experimental/traffic-portal/src/app/core/core.module.ts
index 3a3b39aa96..2d6179d1b2 100644
--- a/experimental/traffic-portal/src/app/core/core.module.ts
+++ b/experimental/traffic-portal/src/app/core/core.module.ts
@@ -22,6 +22,8 @@ import { RouterModule, type Routes } from "@angular/router";
import { DivisionDetailComponent } from
"src/app/core/cache-groups/divisions/detail/division-detail.component";
import { DivisionsTableComponent } from
"src/app/core/cache-groups/divisions/table/divisions-table.component";
+import { RegionDetailComponent } from
"src/app/core/cache-groups/regions/detail/region-detail.component";
+import { RegionsTableComponent } from
"src/app/core/cache-groups/regions/table/regions-table.component";
import { LastDaysComponent } from
"src/app/core/change-logs/last-days/last-days.component";
import { AppUIModule } from "../app.ui.module";
@@ -52,7 +54,9 @@ import { UsersComponent } from "./users/users.component";
export const ROUTES: Routes = [
{ canActivate: [AuthenticatedGuard], component: DashboardComponent,
path: "" },
{ canActivate: [AuthenticatedGuard], component:
DivisionsTableComponent, path: "divisions" },
- { canActivate: [AuthenticatedGuard], component:
DivisionDetailComponent, path: "divisions/:id" },
+ { canActivate: [AuthenticatedGuard], component:
DivisionDetailComponent, path: "division/:id" },
+ { canActivate: [AuthenticatedGuard], component: RegionsTableComponent,
path: "regions" },
+ { canActivate: [AuthenticatedGuard], component: RegionDetailComponent,
path: "region/:id" },
{ canActivate: [AuthenticatedGuard], component: UsersComponent, path:
"users" },
{ canActivate: [AuthenticatedGuard], component: UserDetailsComponent,
path: "users/:id"},
{ canActivate: [AuthenticatedGuard], component: ServersTableComponent,
path: "servers" },
@@ -93,7 +97,9 @@ export const ROUTES: Routes = [
LastDaysComponent,
UserRegistrationDialogComponent,
DivisionsTableComponent,
- DivisionDetailComponent
+ DivisionDetailComponent,
+ RegionsTableComponent,
+ RegionDetailComponent
],
exports: [],
imports: [