blob: a2129d58fb7167358b757c7c4c2c2d254d11b7f9 [file] [log] [blame]
/*
* 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 { Component, type OnDestroy, type OnInit } from "@angular/core";
import type { ValueGetterParams } from "ag-grid-community";
import { BehaviorSubject, type Subscription } from "rxjs";
import { UserService } from "src/app/api";
import type { Tenant } from "src/app/models";
import { CurrentUserService } from "src/app/shared/currentUser/current-user.service";
import type { ContextMenuActionEvent, ContextMenuItem } from "src/app/shared/generic-table/generic-table.component";
import { TpHeaderService } from "src/app/shared/tp-header/tp-header.service";
/**
* TenantsComponent is the controller for the table that lists Tenants.
*/
@Component({
selector: "tp-tenants",
styleUrls: ["./tenants.component.scss"],
templateUrl: "./tenants.component.html"
})
export class TenantsComponent implements OnInit, OnDestroy {
private tenantMap: Record<number, Tenant> = {};
public searchText = "";
public searchSubject = new BehaviorSubject("");
public tenants: Array<Tenant> = [{
active: true,
id: 1,
lastUpdated: new Date(),
name: "root",
parentId: null
}];
/** Definitions of the table's columns according to the ag-grid API */
public columnDefs = [
{
field: "active",
filter: "tpBooleanFilter",
headerName: "Active",
hide: false
},
{
field: "id",
filter: "agNumberColumnFilter",
headerName: "ID",
hide: true,
},
{
field: "lastUpdated",
filter: "agDateColumnFilter",
headerName: "Last Updated",
hide: true,
},
{
field: "name",
headerName: "Name",
hide: false,
},
{
field: "parentId",
headerName: "Parent",
hide: false,
valueGetter: (params: ValueGetterParams): string => this.getParentString(params.data)
}
];
public contextMenuItems: ContextMenuItem<Readonly<Tenant>>[] = [
];
public loading = true;
private readonly subscription: Subscription;
constructor(
private readonly userService: UserService,
public readonly auth: CurrentUserService,
private readonly headerSvc: TpHeaderService
) {
this.headerSvc.headerTitle.next("Tenant");
this.subscription = this.auth.userChanged.subscribe(
() => {
this.loadContextMenuItems();
}
);
}
/**
* Loads the context menu items for the grid.
*
* @private
*/
private loadContextMenuItems(): void {
this.contextMenuItems = [];
if (this.auth.hasPermission("USER:READ")) {
this.contextMenuItems.push({
action: "viewUsers",
multiRow: true,
name: "View Users"
});
}
if (this.auth.hasPermission("TENANT:UPDATE")) {
this.contextMenuItems.push({
action: "disable",
disabled: (ts): boolean => ts.some(t=>t.name === "root" || t.id === this.auth.currentUser?.tenantId),
multiRow: true,
name: "Disable"
});
this.contextMenuItems.push({
href: (t: Tenant): string => `core/tenants/${t.id}`,
name: "View Details"
});
this.contextMenuItems.push({
href: (t: Tenant): string => `core/tenants/${t.id}`,
name: "Open in New Tab",
newTab: true
});
}
}
/**
* Angular lifecycle hook; fetches API data.
*/
public async ngOnInit(): Promise<void> {
this.tenants = await this.userService.getTenants();
this.tenantMap = Object.fromEntries((this.tenants).map(t => [t.id, t]));
this.loadContextMenuItems();
this.loading = false;
}
/**
* Gets a string representation for the Parent of the given Tenant.
*
* @param t The Tenant for which the Parent will be rendered.
* @returns An empty string for the root Tenant, otherwise the parent
* Tenant's name and ID as a string.
*/
public getParentString(t: Tenant): string {
if (t.parentId === null) {
return "";
}
return `${this.tenantMap[t.parentId].name} (#${t.parentId})`;
}
/**
* Angular lifecycle hook; cleans up persistent resources.
*/
public ngOnDestroy(): void {
this.subscription.unsubscribe();
}
/**
* Handles a context menu event.
*
* @param a The action selected from the context menu.
*/
public handleContextMenu(a: ContextMenuActionEvent<Readonly<Tenant>>): void {
console.log("action:", a);
}
/**
* Updates the "search" query parameter in the URL every time the search
* text input changes.
*/
public updateURL(): void {
this.searchSubject.next(this.searchText);
}
}