Feature: 11055 Support of several node groups in clusters created by OSM
- Added control plane support in managed post
- When aws vim account is selected paylaod will get differed
- Added details page in clusters to view node and ksu for
specified cluster
- Fixed Bug 2402 - Unable to create Ns Config template from Ui
bug by chnaging api
Change-Id: I4eb327fd86b0c4a706b05a8ed10524e4d2c5bc95
Signed-off-by: SANDHYA.JS <sandhya.j@tataelxsi.co.in>
diff --git a/src/app/k8s/k8s-info/K8sInfoComponent.html b/src/app/k8s/k8s-info/K8sInfoComponent.html
new file mode 100644
index 0000000..4bf3783
--- /dev/null
+++ b/src/app/k8s/k8s-info/K8sInfoComponent.html
@@ -0,0 +1,248 @@
+<!--
+Copyright 2020 TATA ELXSI
+
+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.
+
+Author: SANDHYA JS (sandhya.j@tataelxsi.co.in)
+-->
+<div class="d-flex flex-row justify-content-between">
+ <div class="col-sm-8 mb-3">
+ <div class="d-flex align-items-center header-style">{{clusterName}}</div>
+ </div>
+</div>
+<div class="btn-group list action" role="group">
+ <button type="button" class="btn btn-block border-0 bg-light collapse text-dark"
+ [ngClass]="{'active': activeButton === 1}" (click)="setActiveButton(1)">
+ <span class="circle">{{(node_count)?node_count:0}}</span>
+ <p>{{'PAGE.K8S.NODE' | translate}}</p>
+ </button>
+ <button type="button" class="btn btn-block border-0 bg-light collapse text-dark"
+ [ngClass]="{'active': activeButton === 2}" (click)="setActiveButton(2)">
+ <span class="circle">{{(ksu_count)?ksu_count:0}}</span>
+ <p>{{'PAGE.K8S.KSU' | translate}}</p>
+ </button>
+</div>
+<div id="demo" class="collapse context-style p-2" *ngIf="isCollapsed2 === true">
+ <div class="container">
+ <span class="button d-flex justify-content-end">
+ <button class="btn btn-primary mb-2 me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Add KSU' | translate}}" (click)="addK8sCluster('card_ksu')">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.ADDKSU' | translate}}
+ </button>
+ </span>
+ <div class="row info gx-3" *ngIf="ksu_count !== 0 else noData">
+ <div *ngFor="let item of ksuDetail" class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4 mb-3">
+ <ng-container *ngIf="item?.package_name.length > 1; else singleCard">
+ <ngb-carousel class="card-carousel" [interval]="0" wrap="true">
+ <ng-template ngbSlide *ngFor="let pkg of item?.package_name; let i = index">
+ <div class="custom-card card">
+ <div class="card-header custom-card-header d-flex justify-content-between">
+ <b style="font-size:medium;">{{ item.name }}</b>
+ <span>
+ <i *ngIf="item.state === 'READY'" class="fas fa-check-circle text-success"
+ data-bs-toggle="tooltip" title="READY"></i>
+ <i *ngIf="item.state.startsWith('IN_PROGRESS')"
+ class="fas fa-spinner text-warning" data-bs-toggle="tooltip"
+ title="{{ item.state }}"></i>
+ <i *ngIf="item.state === 'ERROR'" class="fas fa-times-circle text-danger"
+ data-bs-toggle="tooltip" title="ERROR"></i>
+ </span>
+ </div>
+ <div class="card-body">
+ <p class="label-value-pair-description">
+ <span class="label1">{{ 'PAGE.K8S.DESCRIPTION' | translate }}:</span>
+ <span class="value1">
+ <span class="short-description"
+ (mouseenter)="showPopover($event, item.description)"
+ (mouseleave)="hidePopover()">
+ {{ item.description }}
+ </span>
+ <span class="popover-description" #popover
+ *ngIf="isPopoverVisible && item?.description.length > 15">{{
+ popoverText }}</span>
+ </span>
+ </p>
+ <hr>
+ <p class="label-value-pair">
+ <span class="label">{{ 'PAGE.K8S.PACKAGENAME' | translate }}:</span>
+ <span class="value">{{ item?.package_name[i] }}</span>
+ </p>
+ <p class="label-value-pair">
+ <span class="label">{{ 'PAGE.K8S.PACKAGEPATH' | translate }}:</span>
+ <span class="value">{{ item?.package_path[i] }}</span>
+ </p>
+ <p class="label-value-pair">
+ <span class="label">{{'MODIFIED' | translate }}:</span>
+ <span class="value">{{ item.modified }}</span>
+ </p>
+ </div>
+ <div class="card-footer">
+ <div class="btn-group list" role="group">
+ <button type="button" class="btn btn-primary"
+ (click)='onView(item.identifier, 2)' placement="top" container="body"
+ ngbTooltip="{{'VIEW' | translate}}">
+ <i class="fa fa-eye"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </ng-template>
+ </ngb-carousel>
+ </ng-container>
+ <ng-template #singleCard>
+ <div class="custom-card card">
+ <div class="card-header custom-card-header d-flex justify-content-between">
+ <b style="font-size:medium;">{{ item.name }}</b>
+ <span>
+ <i *ngIf="item.state === 'READY'" class="fas fa-check-circle text-success"
+ data-bs-toggle="tooltip" title="READY"></i>
+ <i *ngIf="item.state.startsWith('IN_PROGRESS')" class="fas fa-spinner text-warning"
+ data-bs-toggle="tooltip" title="{{ item.state }}"></i>
+ <i *ngIf="item.state === 'ERROR'" class="fas fa-times-circle text-danger"
+ data-bs-toggle="tooltip" title="ERROR"></i>
+ </span>
+ </div>
+ <div class="card-body">
+ <p class="label-value-pair-description">
+ <span class="label1">{{ 'PAGE.K8S.DESCRIPTION' | translate}}:</span>
+ <span class="value1">
+ <span class="short-description" (mouseenter)="showPopover($event, item.description)"
+ (mouseleave)="hidePopover()">
+ {{ item.description }}
+ </span>
+ <span class="popover-description" #popover *ngIf="isPopoverVisible">{{
+ popoverText }}</span>
+ </span>
+ </p>
+ <hr>
+ <p class="label-value-pair">
+ <span class="label">{{ 'PAGE.K8S.PACKAGENAME' | translate }}:</span>
+ <span class="value">{{ item?.package_name[0] }}</span>
+ </p>
+ <p class="label-value-pair">
+ <span class="label">{{ 'PAGE.K8S.PACKAGEPATH' | translate }}:</span>
+ <span class="value">{{ item?.package_path[0] }}</span>
+ </p>
+ <p class="label-value-pair">
+ <span class="label">{{ 'MODIFIED' | translate }}:</span>
+ <span class="value">{{ item.modified }}</span>
+ </p>
+ </div>
+ <div class="card-footer">
+ <div class="btn-group list" role="group">
+ <button type="button" class="btn btn-primary" (click)='onView(item.identifier, 2)'
+ placement="top" container="body" ngbTooltip="{{'VIEW' | translate}}">
+ <i class="fa fa-eye"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </ng-template>
+ </div>
+ </div>
+ <ng-template #noData>
+ <div class="no-data">
+ {{ 'NODATA' | translate }}
+ </div>
+ </ng-template>
+ </div>
+</div>
+<div id="demo" class="collapse context-style p-2" *ngIf="isCollapsed1 === true">
+ <div class="container">
+ <span class="button d-flex justify-content-end">
+ <button class="btn btn-primary mb-2 me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Add Node' | translate}}" (click)="addK8sCluster('card_node')">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{ 'PAGE.K8S.ADDNODE' | translate}}
+ </button>
+ </span>
+ <div class="row info gx-3" *ngIf="node_count !== 0 else noData">
+ <div *ngFor="let item of nodeDetail" class="col-12 col-sm-4 col-md-4 col-lg-4 col-xl-4 mb-3">
+ <div class="custom-card card" style="width: 100%; max-width: 20rem;">
+ <div class="card-header custom-card-header d-flex justify-content-between">
+ <b style="font-size:medium;">{{ item.name }}</b>
+ <span class="badge px-2" [ngClass]="{
+ 'bg-danger text-white': item.state === 'ERROR',
+ 'bg-success text-white': item.state === 'READY',
+ 'bg-warning text-white': ['IN_PROGRESS', 'IN_PROGRESS.GIT_SYNCED',
+ 'IN_PROGRESS.KUSTOMIZATION_READY',
+ 'IN_PROGRESS.KUSTOMIZATION_DELETED'].includes(item.state)}">
+ {{ countData?.k8s_version }}
+ </span>
+ <span>
+ <i *ngIf="item.state === 'READY'" class="fas fa-check-circle text-success"
+ data-bs-toggle="tooltip" title="READY"></i>
+ <i *ngIf="item.state.includes('IN_PROGRESS')" class="fas fa-spinner text-warning"
+ data-bs-toggle="tooltip" [title]="item.state"></i>
+ <i *ngIf="item.state === 'ERROR'" class="fas fa-times-circle text-danger"
+ data-bs-toggle="tooltip" title="ERROR"></i>
+ </span>
+ </div>
+ <div class="card-body">
+ <p class="label-value-pair-description">
+ <span class="label1">{{ 'PAGE.K8S.DESCRIPTION' | translate }}:</span>
+ <span class="value1">
+ <span class="short-description" (mouseenter)="showPopover($event, item.description)"
+ (mouseleave)="hidePopover()">
+ {{ item.description }}
+ </span>
+ <span class="popover-description" #popover
+ *ngIf="isPopoverVisible && item?.description.length > 15">{{ popoverText
+ }}</span>
+ </span>
+ </p>
+ <hr>
+ <p class="label-value-pair"><span class="label">{{ 'PAGE.K8S.NODESIZE' | translate }}:</span>
+ <span class="value">{{
+ item.nodeSize }}</span>
+ </p>
+ <p class="label-value-pair"><span class="label">{{ 'PAGE.K8S.NODECOUNT' | translate }}:</span>
+ <span class="value">{{ item.nodeCount }}</span>
+ </p>
+ <p class="label-value-pair"><span class="label">{{ 'MODIFIED' | translate }}:</span> <span
+ class="value">{{ item.modified }}</span></p>
+ </div>
+ <div class="card-footer">
+ <div class="btn-group list" role="group">
+ <button type="button" class="btn btn-primary" (click)='onView(item.identifier, 1)'
+ placement="top" container="body" ngbTooltip="{{'VIEW' | translate}}">
+ <i class="fa fa-eye"></i>
+ </button>
+ <button type="button" class="btn btn-primary" placement="top" container="body"
+ ngbTooltip="{{'EDIT' | translate}}" [disabled]="item.state !== 'READY'"
+ (click)='scaling(item.identifier, "edit-node")'>
+ <i class="fas fa-edit"></i>
+ </button>
+ <button type="button" class="btn btn-primary" placement="top" container="body"
+ ngbTooltip="{{'DELETE' | translate}}"
+ [disabled]="item.state !== 'READY' && item.state !== 'ERROR'"
+ (click)='onDelete(item.identifier, item.name, 1)'>
+ <i class="far fa-trash-alt icons"></i>
+ </button>
+ <button type="button" class="btn btn-primary" placement="top" container="body"
+ ngbTooltip="{{'PAGE.K8S.K8SSCALING' | translate}}" [disabled]="item.state !== 'READY'"
+ (click)='scaling(item.identifier, "k8s-scale")'>
+ <i class="fas fa-arrows-alt-v"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <ng-template #noData>
+ <div class="no-data">
+ {{ 'NODATA' | translate }}
+ </div>
+ </ng-template>
+ </div>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-info/K8sInfoComponent.scss b/src/app/k8s/k8s-info/K8sInfoComponent.scss
new file mode 100644
index 0000000..d3b10b6
--- /dev/null
+++ b/src/app/k8s/k8s-info/K8sInfoComponent.scss
@@ -0,0 +1,314 @@
+/*
+ Copyright 2020 TATA ELXSI
+
+ 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.
+
+ Author: SANDHYA JS (sandhya.j@tataelxsi.co.in)
+*/
+@import "../../../assets/scss/variable.scss";
+@import "../../../assets/scss/mixins/mixin.scss";
+
+.text-dark {
+ color: $gray-800;
+}
+
+.font-weight-bold {
+ font-weight: 700;
+}
+
+button.bg-light {
+ background-color: $gray-200;
+ &:hover,
+ &:focus {
+ background-color: $paleblue;
+ }
+}
+
+.btn-group {
+ display: flex;
+ &.list.action {
+ justify-content: center;
+ align-items: flex-start;
+ flex-wrap: wrap;
+ .btn {
+ border-top: 2px solid $primary;
+ transition:
+ transform 0.3s ease-in-out,
+ background-color 0.3s,
+ color 0.3s;
+ &.active {
+ background-color: $theme-bg-color;
+ font-weight: bold;
+ margin: 5px 0 0;
+ transform: scale(1);
+ .circle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background-color: $primary;
+ color: white;
+ position: absolute;
+ top: 0;
+ transform: translateY(-50%);
+ }
+ b {
+ font-size: 1.2em;
+ }
+ p {
+ font-size: 1em;
+ }
+ }
+ &:not(.active) {
+ transform: scale(0.97);
+ opacity: 0.8;
+ .circle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background-color: $gray-200;
+ color: black;
+ position: absolute;
+ top: 0;
+ transform: translateY(-50%);
+ border: 1px solid $primary;
+ }
+ }
+ }
+ .collapse {
+ transition:
+ background-color 0.3s,
+ color 0.3s;
+ }
+ }
+}
+.collapse {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-start;
+ padding: 5px;
+ background-color: $theme-bg-color;
+}
+
+.btn p {
+ margin: 0;
+ padding-top: 20px;
+}
+
+.label-value-pair,
+.label-value-pair-description {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+ @include padding-value(3, 10, 0, 10);
+ align-items: center;
+ gap: 8px;
+ position: relative;
+}
+
+.label,
+.label1 {
+ font-weight: bold;
+ color: #343a40;
+ white-space: nowrap;
+}
+
+.value,
+.value1 {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ cursor: pointer;
+ max-height: 3em;
+ line-height: 1.5em;
+ position: relative;
+ margin-left: 5px;
+ color: #343a40;
+ flex: 1;
+ min-width: 0;
+ overflow: visible;
+}
+
+.custom-card {
+ @include wh-value(null, 290px);
+ @include roundedCorners(5);
+ position: relative;
+ @include border(all, 1, solid, rgba(238, 238, 238, 0.75));
+ @include box-shadow(0px, 1px, 15px, 0px, rgba(69, 90, 100, 0.1));
+ background-color: $white;
+}
+
+.d-flex {
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ gap: 2px;
+ width: 100%;
+}
+
+.search-container {
+ position: relative;
+ width: 100%;
+ max-width: 300px;
+ height: 30px;
+ display: flex;
+}
+
+.search-input {
+ width: 100%;
+ padding-right: 40px;
+ box-sizing: border-box;
+ border: 1px solid $primary;
+}
+
+.search-icon {
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: $primary;
+}
+
+.sort-dropdown {
+ display: flex;
+ align-items: center;
+ position: relative;
+ flex-shrink: 0;
+ min-width: 150px;
+ max-width: 200px;
+ margin-left: 2px;
+}
+
+#sort-icon {
+ margin-right: 10px;
+ cursor: pointer;
+}
+
+#sort-options {
+ padding: 2px;
+ cursor: pointer;
+}
+
+.custom-card-header {
+ background-color: $primary;
+ @include box-shadow(0px, 1px, 15px, 0px, rgba(69, 90, 100, 0.1));
+ @include roundedCorners(5);
+ color: white;
+}
+
+.version {
+ background-color: $secondary;
+ width: 40px;
+}
+
+.short-description {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ cursor: pointer;
+ max-height: 3em;
+ line-height: 1.5em;
+ white-space: normal;
+ line-clamp: 2;
+}
+
+/* Tooltip Styling */
+.popover-description {
+ position: absolute;
+ background-color: $primary;
+ color: white;
+ padding: 8px;
+ border-radius: 5px;
+ font-size: 12px;
+ max-width: 300px;
+ white-space: normal;
+ display: none;
+ z-index: 1000;
+}
+
+.value1:hover .popover-description {
+ display: block;
+}
+
+.card-header,
+.card-footer {
+ padding: 12px;
+ font-weight: bold;
+}
+
+.card-body {
+ padding: 0;
+ margin: 0;
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+}
+
+.no-data {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 20px 0;
+ text-align: center;
+ height: 260px;
+}
+
+::ng-deep .carousel-indicators {
+ display: none;
+}
+
+/* Hide default Bootstrap background images for arrows */
+::ng-deep .carousel-control-prev-icon,
+::ng-deep .carousel-control-next-icon {
+ background-image: none;
+ display: none;
+}
+
+/* Add Font Awesome icons for Previous & Next Arrows */
+::ng-deep .carousel-control-prev::before {
+ content: "\f104";
+ font-family: "Font Awesome 5 Free";
+ font-weight: 900;
+ width: 20px;
+ height: 20px;
+ position: relative;
+ color: white;
+ right: 22px;
+ bottom: 35px;
+ background-color: $primary;
+ border-radius: 50%;
+}
+
+::ng-deep .carousel-control-next::before {
+ content: "\f105";
+ font-family: "Font Awesome 5 Free";
+ font-weight: 900;
+ position: relative;
+ left: 22px;
+ bottom: 35px;
+ width: 20px;
+ height: 20px;
+ color: white;
+ background-color: $primary;
+ border-radius: 50%;
+}
diff --git a/src/app/k8s/k8s-info/K8sInfoComponent.ts b/src/app/k8s/k8s-info/K8sInfoComponent.ts
new file mode 100644
index 0000000..7a9d577
--- /dev/null
+++ b/src/app/k8s/k8s-info/K8sInfoComponent.ts
@@ -0,0 +1,373 @@
+/*
+ Copyright 2020 TATA ELXSI
+
+ 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.
+
+ Author: SANDHYA JS (sandhya.j@tataelxsi.co.in)
+*/
+/**
+ * @file Info K8s Page
+ */
+import { Component, HostListener, Injector, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DeleteComponent } from 'DeleteComponent';
+import { environment } from 'environment';
+import { K8SCLUSTERDATA, K8SCLUSTERDATADISPLAY, K8SNODEDATA } from 'K8sModel';
+import { KSUAddComponent } from 'KSUAddComponent';
+import { NodeAddComponent } from 'NodeAddComponent';
+import { RestService } from 'RestService';
+import { isNullOrUndefined, SharedService } from 'SharedService';
+import { ShowInfoComponent } from 'ShowInfoComponent';
+
+/**
+ * Creating component
+ * @Component K8sInfoComponent.html as template url
+ */
+@Component({
+ selector: 'app-info-k8s',
+ templateUrl: './K8sInfoComponent.html',
+ styleUrls: ['./K8sInfoComponent.scss']
+})
+/** Exporting a class @exports K8sInfoComponent */
+export class K8sInfoComponent implements OnInit {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** Contains active button @public */
+ public activeButton = 1;
+
+ /** condition to show tooltip @public */
+ public showTooltip = false;
+
+ /** Showing more details of collapase */
+ public isCollapsed1: boolean = true;
+
+ /** Showing more details of collapase */
+ public isCollapsed2: boolean = false;
+
+ /** Check the Projects loading results @public */
+ public isLoadingResults: boolean = false;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** variables contains paramsID @public */
+ public paramsID: string;
+
+ /** Contains cluster name @public */
+ public clusterName: string;
+
+ /** Contains cluster data with count @public */
+ public countData: K8SCLUSTERDATA = {};
+
+ /** Contains node count @public */
+ public node_count: number;
+
+ /** Contains ksu count @public */
+ public ksu_count: number;
+
+ /** Contains node details @public */
+ public nodeDetail: {}[] = [];
+
+ /** Contains ksu details @public */
+ public ksuDetail: {}[] = [];
+
+ /** Condition for popover visibility @public */
+ public isPopoverVisible = false;
+
+ /** Contains popover text to show @public */
+ public popoverText = '';
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** Holds teh instance of AuthService class of type AuthService @private */
+ private activatedRoute: ActivatedRoute;
+
+ /** Utilizes modal service for any modal operations @private */
+ private modalService: NgbModal;
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.activatedRoute = this.injector.get(ActivatedRoute);
+ this.modalService = this.injector.get(NgbModal);
+ this.sharedService = this.injector.get(SharedService);
+ }
+
+ /**
+ * Lifecyle Hooks the trigger before component is instantiate
+ */
+ public ngOnInit(): void {
+ this.paramsID = this.activatedRoute.snapshot.paramMap.get('id');
+ this.generateData();
+ }
+
+ /** To view Details @public */
+ public onView(identifier: string, type: number): void {
+ let pageName: string = '';
+ let title: string = '';
+ if (type === 1) {
+ pageName = 'k8s-node';
+ title = 'Node Details';
+ } else {
+ pageName = 'k8s-ksu';
+ title = 'KSU Details';
+ }
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ this.modalService.open(ShowInfoComponent, { backdrop: 'static' }).componentInstance.params = {
+ id: identifier,
+ page: pageName,
+ titleName: title,
+ cluster_id: this.paramsID
+ };
+ }
+
+ /** Edit Node @public */
+ public onEdit(type: number): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(NodeAddComponent, { backdrop: 'static' });
+ if (type === 1) {
+ modalRef.componentInstance.profileType = 'card-node';
+ }
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Delete Operation @public */
+ public onDelete(id_value: string, name_value: string, type: number): void {
+ let pageName: string = '';
+ let title: string = '';
+ if (type === 1) {
+ pageName = 'card-node';
+ title = 'Node Details';
+ } else {
+ pageName = 'card-ksu';
+ title = 'KSU Details';
+ }
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
+ modalRef.componentInstance.params = {
+ id: id_value,
+ page: pageName,
+ titleName: 'Node Details',
+ cluster_id: this.paramsID,
+ name: name_value
+ };
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ this.nodeData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** popover functionality to show full description @public */
+ public showPopover(event: MouseEvent, description: string) {
+ this.popoverText = description;
+ this.isPopoverVisible = true;
+ const popover = (event.target as HTMLElement).nextElementSibling as HTMLElement;
+ if (popover) {
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ popover.style.top = `${event.clientY + 10}px`;
+ popover.style.left = `${event.clientX}px`;
+ }
+ }
+
+ /** To hide popover @public */
+ public hidePopover() {
+ this.isPopoverVisible = false;
+ }
+
+ /** Add Node/KSU @public */
+ public addK8sCluster(type?: string): void {
+ if (type === 'card_node') {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(NodeAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = type;
+ modalRef.componentInstance.clusterId = this.paramsID;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ this.nodeData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ } else if (type === 'card_ksu') {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'card-add';
+ modalRef.componentInstance.profileID = this.paramsID;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ this.ksuData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+ }
+
+ /** Close tooltip when clicking outside @public */
+ @HostListener('document:click', ['$event'])
+ closeTooltip(event: Event) {
+ if (!(event.target as HTMLElement).classList.contains('short-description')) {
+ this.showTooltip = false;
+ }
+ }
+ /** Generate nodeData object from loop and return for the datasource @public */
+ public generateNodeData(nodedata: K8SCLUSTERDATA): K8SCLUSTERDATADISPLAY {
+ return {
+ name: nodedata.name,
+ state: !isNullOrUndefined(nodedata.resourceState) ? nodedata.resourceState : 'N/A',
+ identifier: nodedata._id,
+ version: nodedata.k8s_version,
+ description: !isNullOrUndefined(nodedata.description) ? nodedata.description : '-',
+ nodeCount: nodedata.node_count,
+ nodeSize: nodedata.node_size,
+ created: !isNullOrUndefined(nodedata?._admin?.created) ? this.sharedService.convertEpochTime(Number(nodedata._admin.created)) : '-',
+ modified: !isNullOrUndefined(nodedata?._admin?.modified) ? this.sharedService.convertEpochTime(Number(nodedata._admin.modified)) : '-'
+ };
+ }
+ /** Generate ksuData object from loop and return for the datasource @public */
+ public generateKsuData(ksudata: K8SCLUSTERDATA): K8SCLUSTERDATADISPLAY {
+ return {
+ name: ksudata.name,
+ state: !isNullOrUndefined(ksudata.resourceState) ? ksudata.resourceState : 'N/A',
+ identifier: ksudata._id,
+ version: ksudata.k8s_version,
+ description: !isNullOrUndefined(ksudata.description) ? ksudata.description : '-',
+ package_name: ksudata.package_name,
+ package_path: ksudata.package_path,
+ created: !isNullOrUndefined(ksudata?._admin?.created) ? this.sharedService.convertEpochTime(Number(ksudata._admin.created)) : '-',
+ modified: !isNullOrUndefined(ksudata?._admin?.modified) ? this.sharedService.convertEpochTime(Number(ksudata._admin.modified)) : '-'
+ };
+ }
+
+ /** Generate k8s Data function @public */
+ public generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SCREATECLUSTER_URL + '/' + this.paramsID).subscribe((k8sClusterDatas: K8SCLUSTERDATA) => {
+ if (!isNullOrUndefined(k8sClusterDatas)) {
+ this.node_count = k8sClusterDatas.node_count;
+ this.ksu_count = k8sClusterDatas.ksu_count;
+ this.countData = k8sClusterDatas;
+ this.clusterName = k8sClusterDatas.name;
+ this.nodeData();
+ }
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Generate node Data function @public */
+ public nodeData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SCREATECLUSTER_URL + '/' + this.paramsID + '/nodegroup').subscribe((k8sClusterDatas: K8SCLUSTERDATA) => {
+ if (!isNullOrUndefined(k8sClusterDatas)) {
+ this.nodeDetail = [];
+ this.node_count = k8sClusterDatas.count;
+ k8sClusterDatas.data?.forEach((clusterData: K8SNODEDATA) => {
+ const k8sClusterDataObj: K8SCLUSTERDATADISPLAY = this.generateNodeData(clusterData);
+ this.nodeDetail.push(k8sClusterDataObj);
+ });
+ }
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Generate ksu Data function @public */
+ public ksuData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SCREATECLUSTER_URL + '/' + this.paramsID + '/ksus').subscribe((k8sClusterDatas: K8SCLUSTERDATA) => {
+ if (!isNullOrUndefined(k8sClusterDatas)) {
+ this.ksuDetail = [];
+ this.ksu_count = k8sClusterDatas.count;
+ k8sClusterDatas.data?.forEach((clusterData: K8SNODEDATA) => {
+ const k8sClusterDataObj: K8SCLUSTERDATADISPLAY = this.generateKsuData(clusterData);
+ this.ksuDetail.push(k8sClusterDataObj);
+ });
+ }
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** To capture active button @public */
+ public setActiveButton(buttonNumber: number) {
+ this.activeButton = buttonNumber;
+ if (buttonNumber === 1) {
+ this.nodeData();
+ this.isCollapsed1 = true;
+ this.isCollapsed2 = false;
+ } else if (buttonNumber === 2) {
+ this.ksuData();
+ this.isCollapsed2 = true;
+ this.isCollapsed1 = false;
+ }
+ }
+
+ /** Scaling @public */
+ public scaling(id: string, type?: string): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(NodeAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.clusterId = this.paramsID;
+ modalRef.componentInstance.profileID = id;
+ modalRef.componentInstance.profileType = type;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ this.nodeData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Edit KSU @public */
+ public editKsu(id?: string): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = id;
+ modalRef.componentInstance.profileType = 'edit';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ this.ksuData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+}