Advanced Cluster Management - NGUI
- Added new OKA packages module under packages
- Added Profiless, KSU under k8s section
- Feature 11020. 11022, 11023, 11024, 11025, 11026
Change-Id: Ibddeb4d5693ce24d80e378277693405c810f6e04
Signed-off-by: SANDHYA.JS <sandhya.j@tataelxsi.co.in>
diff --git a/src/app/k8s/K8sModule.ts b/src/app/k8s/K8sModule.ts
index 14d8165..4b9ff15 100644
--- a/src/app/k8s/K8sModule.ts
+++ b/src/app/k8s/K8sModule.ts
@@ -31,9 +31,17 @@
import { K8sActionComponent } from 'K8sActionComponent';
import { K8sAddClusterComponent } from 'K8sAddClusterComponent';
import { K8sAddRepoComponent } from 'K8sAddRepoComponent';
+import { K8sAppProfileComponent } from 'K8sAppProfileComponent';
+import { K8sAttachProfileComponent } from 'K8sAttachProfileComponent';
import { K8sClusterComponent } from 'K8sClusterComponent';
import { K8sComponent } from 'K8sComponent';
+import { K8sInfraConfigAddComponent } from 'K8sInfraConfigAddComponent';
+import { K8sInfraConfigProfileComponent } from 'K8sInfraConfigProfileComponent';
+import { K8sInfraControllerProfileComponent } from 'K8sInfraControllerProfileComponent';
import { K8sRepositoryComponent } from 'K8sRepositoryComponent';
+import { K8sResourceProfileComponent } from 'K8sResourceProfileComponent';
+import { KSUAddComponent } from 'KSUAddComponent';
+import { KSUComponent } from 'KSUComponent';
import { LoaderModule } from 'LoaderModule';
import { Ng2SmartTableModule } from 'ng2-smart-table';
import { PagePerRowModule } from 'PagePerRowModule';
@@ -59,6 +67,46 @@
component: K8sClusterComponent
},
{
+ path: 'infra-config-profile',
+ data: {
+ breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
+ projectInfo, { title: 'PAGE.K8S.INFRACONFIG', url: null }]
+ },
+ component: K8sInfraConfigProfileComponent
+ },
+ {
+ path: 'infra-controller-profile',
+ data: {
+ breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
+ projectInfo, { title: 'PAGE.K8S.INFRACONTROLLER', url: null }]
+ },
+ component: K8sInfraControllerProfileComponent
+ },
+ {
+ path: 'app-profile',
+ data: {
+ breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
+ projectInfo, { title: 'PAGE.K8S.APP', url: null }]
+ },
+ component: K8sAppProfileComponent
+ },
+ {
+ path: 'resource-profile',
+ data: {
+ breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
+ projectInfo, { title: 'PAGE.K8S.RESOURCE', url: null }]
+ },
+ component: K8sResourceProfileComponent
+ },
+ {
+ path: 'ksu',
+ data: {
+ breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
+ projectInfo, { title: 'PAGE.K8S.KSU', url: null }]
+ },
+ component: KSUComponent
+ },
+ {
path: 'repo',
data: {
breadcrumb: [{ title: 'PAGE.DASHBOARD.DASHBOARD', url: '/' }, { title: 'PAGE.DASHBOARD.PROJECTS', url: '/projects' },
@@ -93,7 +141,15 @@
K8sRepositoryComponent,
K8sActionComponent,
K8sAddClusterComponent,
- K8sAddRepoComponent
+ K8sAddRepoComponent,
+ K8sAttachProfileComponent,
+ K8sInfraConfigProfileComponent,
+ K8sInfraControllerProfileComponent,
+ K8sInfraConfigAddComponent,
+ K8sAppProfileComponent,
+ K8sResourceProfileComponent,
+ KSUComponent,
+ KSUAddComponent
],
providers: [DataService],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
diff --git a/src/app/k8s/k8s-action/K8sActionComponent.html b/src/app/k8s/k8s-action/K8sActionComponent.html
index c35bb19..ddce99c 100644
--- a/src/app/k8s/k8s-action/K8sActionComponent.html
+++ b/src/app/k8s/k8s-action/K8sActionComponent.html
@@ -16,12 +16,78 @@
Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
-->
<div class="btn-group list action" role="group">
- <button type="button" class="btn btn-primary" (click)="infoK8s(getK8sType)" placement="top" container="body"
- ngbTooltip="{{'INFO' | translate}}">
+ <button *ngIf="getK8sType === 'repo'" type="button" class="btn btn-primary" (click)="infoK8s(getK8sType)"
+ placement="top" container="body" ngbTooltip="{{'INFO' | translate}}">
<i class="fas fa-info icons list" title="info"></i>
</button>
- <button type="button" class="btn btn-primary" (click)="deleteK8s(getK8sType)" placement="top"
- container="body" ngbTooltip="{{'DELETE' | translate}}">
+ <button *ngIf="(isCluster || isProfile || isKSU) && getK8sType !== 'repo' && !checkRegister" [disabled]="state != 'CREATED'"
+ type="button" class="btn btn-primary" (click)="deleteK8s()" placement="top" container="body"
+ ngbTooltip="{{'DELETE' | translate}}">
<i class="far fa-trash-alt icons" title="delete"></i>
</button>
-</div>
\ No newline at end of file
+ <button *ngIf="(!isCluster || !isProfile || !isKSU) && getK8sType === 'repo'" type="button" class="btn btn-primary"
+ (click)="deleteK8s()" placement="top" container="body" ngbTooltip="{{'DELETE' | translate}}">
+ <i class="far fa-trash-alt icons" title="delete"></i>
+ </button>
+ <button *ngIf="checkRegister && !isCluster && !isProfile && !isKSU && getK8sType !== 'repo'"
+ [disabled]="state != 'CREATED'" type="button" class="btn btn-primary" (click)="deleteK8s()" placement="top"
+ container="body" ngbTooltip="{{'DEREGISTER' | translate}}">
+ <i class="fas fa-window-close icons" title="deregister"></i>
+ </button>
+ <div *ngIf="isCluster && !isProfile && !isKSU && getK8sType !== 'repo'" class="btn-group" placement="bottom-right" ngbDropdown
+ display="dynamic" container="body">
+ <button type="button" class="btn btn-primary" [disabled]="state != 'CREATED'" ngbDropdownToggle placement="top" container="body"
+ ngbTooltip="{{'Attach Profile' | translate}}">
+ <i class="fas fa-link"></i>
+ </button>
+ <div class="dropdown-menu list-action-dropdown" ngbDropdownMenu>
+ <button type="button" class="btn btn-primary dropdown-item" placement="left" container="body"
+ (click)="editClusterProfile('infra-config')" ngbTooltip="{{'PAGE.K8S.ATTACHINFRACONFIG' | translate}}">
+ <i class="fa fa-link"></i> {{'PAGE.K8S.ATTACHINFRACONFIG' | translate}}
+ </button>
+ <button type="button" class="btn btn-primary dropdown-item" (click)="editClusterProfile('infra-controller')"
+ placement="left" container="body" ngbTooltip="{{'PAGE.K8S.ATTACHINFRACONTROLLER' | translate}}">
+ <i class="fas fa-link"></i> {{'PAGE.K8S.ATTACHINFRACONTROLLER' | translate}}
+ </button>
+ <button type="button" class="btn btn-primary dropdown-item" placement="left"
+ (click)="editClusterProfile('app-profile')" container="body" ngbTooltip="{{'PAGE.K8S.ATTACHAPP' | translate}}">
+ <i class="fas fa-link"></i> {{'PAGE.K8S.ATTACHAPP' | translate}}
+ </button>
+ <button type="button" class="btn btn-primary dropdown-item" placement="left"
+ (click)="editClusterProfile('resource-profile')" container="body"
+ ngbTooltip="{{'PAGE.K8S.ATTACHRESOURCE' | translate}}">
+ <i class="fas fa-link"></i> {{'PAGE.K8S.ATTACHRESOURCE' | translate}}
+ </button>
+ </div>
+ </div>
+ <div *ngIf="(isProfile || isKSU || isCluster && getK8sType !== 'repo')" class="btn-group" ngbDropdown display="dynamic" container="body">
+ <button type="button" [disabled]="state != 'CREATED'" class="btn btn-primary dropdown-toggle action-button" ngbDropdownToggle>
+ {{'ACTION' | translate}}
+ </button>
+ <div class="dropdown-menu list-action-dropdown" ngbDropdownMenu>
+ <button *ngIf="isProfile && !KSU && !isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" container="body" (click)="editProfile(getK8sType)" ngbTooltip="{{'PAGE.K8S.EDITPROFILE' | translate}}">
+ <i class="fa fa-edit icons"></i> {{'PAGE.K8S.EDITPROFILE' | translate}}
+ </button>
+ <button *ngIf="isKSU && !isProfile && !isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" (click)="moveKsu()" container="body" ngbTooltip="{{'PAGE.K8S.MOVE' | translate}}">
+ <i class="fas fa-truck-moving"></i> {{'PAGE.K8S.MOVE' | translate}}
+ </button>
+ <button *ngIf="isKSU && !isProfile && !isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" (click)="cloneKsu()" container="body" ngbTooltip="{{'PAGE.K8S.CLONE' | translate}}">
+ <i class="fa fa-clone icons"></i> {{'PAGE.K8S.CLONE' | translate}}
+ </button>
+ <button *ngIf="isKSU && !isProfile && !isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" (click)="editKsu()" container="body" ngbTooltip="{{'EDIT' | translate}}">
+ <i class="fa fa-edit icons"></i> {{'EDIT' | translate}}
+ </button>
+ <button *ngIf="!isKSU && !isProfile && isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" (click)="editCluster('upgrade')" container="body" ngbTooltip="{{'PAGE.K8S.UPGRADE' | translate}}">
+ <i class="fa fa-arrow-up"></i> {{'PAGE.K8S.UPGRADE' | translate}}
+ </button>
+ <button *ngIf="!isKSU && !isProfile && isCluster" type="button" class="btn btn-primary dropdown-item"
+ placement="left" (click)="editCluster('scale')" container="body" ngbTooltip="{{'PAGE.K8S.SCALE' | translate}}">
+ <i class="fas fa-compress-alt"></i> {{'PAGE.K8S.SCALE' | translate}}
+ </button>
+ </div>
+ </div>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-action/K8sActionComponent.ts b/src/app/k8s/k8s-action/K8sActionComponent.ts
index f68eff6..eef33ca 100644
--- a/src/app/k8s/k8s-action/K8sActionComponent.ts
+++ b/src/app/k8s/k8s-action/K8sActionComponent.ts
@@ -7,7 +7,7 @@
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
+ 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
@@ -23,7 +23,11 @@
import { TranslateService } from '@ngx-translate/core';
import { MODALCLOSERESPONSEDATA } from 'CommonModel';
import { DeleteComponent } from 'DeleteComponent';
-import { K8SCLUSTERDATADISPLAY, K8SREPODATADISPLAY } from 'K8sModel';
+import { K8sAddClusterComponent } from 'K8sAddClusterComponent';
+import { K8sAttachProfileComponent } from 'K8sAttachProfileComponent';
+import { K8sInfraConfigAddComponent } from 'K8sInfraConfigAddComponent';
+import { INFRACONFIGPAYLOAD, K8SCLUSTERDATADISPLAY, K8SPayload, K8SREPODATADISPLAY } from 'K8sModel';
+import { KSUAddComponent } from 'KSUAddComponent';
import { SharedService } from 'SharedService';
import { ShowInfoComponent } from 'ShowInfoComponent';
/**
@@ -36,19 +40,34 @@
styleUrls: ['./K8sActionComponent.scss']
})
/** Exporting a class @exports K8sActionComponent */
-export class K8sActionComponent{
+export class K8sActionComponent {
/** To inject services @public */
public injector: Injector;
/** To get the value from the Users action via valuePrepareFunction default Property of ng-smarttable @public */
- public value: K8SCLUSTERDATADISPLAY | K8SREPODATADISPLAY;
+ public value: K8SCLUSTERDATADISPLAY | K8SREPODATADISPLAY | INFRACONFIGPAYLOAD;
/** handle translate @public */
public translateService: TranslateService;
- /** Contains K8s Type @private */
+ /** Contains K8s Type @public */
public getK8sType: string;
+ /** Check register page @public */
+ public checkRegister = false;
+
+ /** Contains state @public */
+ public state: string;
+
+ /** Check profile or not @public */
+ public isProfile = false;
+
+ /** Check ksu or not @public */
+ public isKSU = false;
+
+ /** Check cluster or not @public */
+ public isCluster = false;
+
/** Instance of the modal service @private */
private modalService: NgbModal;
@@ -71,10 +90,28 @@
public ngOnInit(): void {
this.instanceID = this.value.identifier;
this.getK8sType = this.value.pageType;
+ this.state = this.value.state;
+ if (sessionStorage.getItem('clusterType') === 'Registered') {
+ this.checkRegister = true;
+ }
+ if (this.getK8sType === 'infra-config' || this.getK8sType === 'infra-controller' || this.getK8sType === 'app-profile' || this.getK8sType === 'resource-profile') {
+ this.isCluster = false;
+ this.isProfile = true;
+ this.isKSU = false;
+ } else if (sessionStorage.getItem('clusterType') === 'Managed') {
+ this.isCluster = true;
+ this.isProfile = false;
+ this.isKSU = false;
+ }
+ if (this.getK8sType === 'k8-ksu') {
+ this.isKSU = true;
+ this.isCluster = false;
+ this.isProfile = false;
+ }
}
/** Delete User Account @public */
- public deleteK8s(pageType: string): void {
+ public deleteK8s(): void {
// eslint-disable-next-line security/detect-non-literal-fs-filename
const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
@@ -83,7 +120,7 @@
}
}).catch((): void => {
// Catch Navigation Error
- });
+ });
}
/** Shows information using modalservice @public */
@@ -104,4 +141,96 @@
titleName: title
};
}
+ /** Edit profile @public */
+ public editProfile(editType: string): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sInfraConfigAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = editType;
+ modalRef.componentInstance.profileName = this.value.name;
+ modalRef.componentInstance.profileDescription = this.value.description;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Edit cluster @public */
+ public editCluster(editType: string): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sAddClusterComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = editType;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+
+ /** Edit profile under cluster @public */
+ public editClusterProfile(editType: string): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sAttachProfileComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = editType;
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Move KSU @public */
+ public moveKsu(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = 'move';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Edit KSU @public */
+ public editKsu(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = 'edit';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /** Clone KSU @public */
+ public cloneKsu(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileID = this.value.identifier;
+ modalRef.componentInstance.profileType = 'clone';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
}
diff --git a/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.html b/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.html
index 707d8d6..a8d5820 100644
--- a/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.html
+++ b/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.html
@@ -17,22 +17,30 @@
-->
<form [formGroup]="k8sclusterForm" (ngSubmit)="k8sAddClusterSubmit();">
<div class="modal-header">
- <h4 class="modal-title" id="modal-basic-title">{{'PAGE.K8S.NEWK8SCLUSTER' | translate}}</h4>
+ <h4 *ngIf="profileType === 'Register'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.REGISTERCLUSTER' | translate}}
+ </h4>
+ <h4 *ngIf="profileType === 'Manage'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.CREATECLUSTER' | translate}}
+ </h4>
+ <h4 *ngIf="profileType === 'upgrade'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.UPGRADECLUSTER' | translate}}
+ </h4>
+ <h4 *ngIf="profileType === 'scale'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.SCALECLUSTER' | translate}}</h4>
<button class="button-xs" type="button" class="close" aria-label="Close" (click)="activeModal.close()">
<i class="fas fa-times-circle text-danger"></i>
</button>
</div>
<div class="modal-body modal-body-custom-height">
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'Register'">
<label class="col-sm-12 col-form-label mandatory-label"
- [ngClass]="{'text-danger': k8sclusterForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' | translate}}</label>
+ [ngClass]="{'text-danger': k8sclusterForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
+ translate}}</label>
<label class="col-sm-4 col-form-label" for="name">{{'PAGE.K8S.NAME' | translate}}*</label>
<div class="col-sm-8">
<input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NAME' | translate}}" type="text"
formControlName="name" id="name" [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
</div>
</div>
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3"
+ *ngIf="profileType === 'Manage' || profileType === 'Register'|| profileType === 'upgrade'">
<label class="col-sm-4 col-form-label" for="k8s_version">{{'PAGE.K8S.K8SVERSION' | translate}}*</label>
<div class="col-sm-8">
<input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.K8SVERSION' | translate}}" type="text"
@@ -40,28 +48,28 @@
required>
</div>
</div>
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'Register'">
<label class="col-sm-4 col-form-label" for="vim_account">{{'PAGE.K8S.VIMACCOUNT' | translate}}*</label>
<div class="col-sm-8">
- <ng-select placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.VIMACCOUNT' | translate}}"
- [items]="vimAccountSelect" bindLabel="name" bindValue="_id" formControlName="vim_account" id="vimAccountId"
+ <ng-select (change)="getDetailsvim($event)"
+ placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.VIMACCOUNT' | translate}}" [items]="vimAccountSelect"
+ bindLabel="name" bindValue="name" formControlName="vim_account" id="vimAccountId"
[ngClass]="{ 'is-invalid': submitted && f.vim_account.errors }" required>
</ng-select>
</div>
</div>
- <div class="form-group row mb-3">
- <label class="col-sm-4 col-form-label" for="deployment_methods">{{'PAGE.K8S.DEPLOYMENTMETHODS' | translate}}*</label>
+ <div class="form-group row mb-3" *ngIf="profileType === 'Register'">
+ <label class="col-sm-4 col-form-label" for="deployment_methods">{{'PAGE.K8S.DEPLOYMENTMETHODS' |
+ translate}}*</label>
<div class="col-sm-8">
- <ng-select placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.DEPLOYMENTMETHODS' | translate}}"
- multiple="true"
- [items]="deploymentMethodsSelect" bindLabel="title" bindValue="value" formControlName="deployment_methods" id="deploymentMethodsId"
- [ngClass]="{ 'is-invalid': submitted && f.deployment_methods.errors }"
- [(ngModel)]="selectedDeploymentMethods"
- required>
+ <ng-select placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.DEPLOYMENTMETHODS' | translate}}" multiple="true"
+ [items]="deploymentMethodsSelect" bindLabel="title" bindValue="value" formControlName="deployment_methods"
+ id="deploymentMethodsId" [ngClass]="{ 'is-invalid': submitted && f.deployment_methods.errors }"
+ [(ngModel)]="selectedDeploymentMethods" required>
</ng-select>
</div>
</div>
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'Register'">
<label class="col-sm-4 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}*</label>
<div class="col-sm-8">
<textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
@@ -69,7 +77,7 @@
required></textarea>
</div>
</div>
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3" *ngIf="profileType === 'Register'">
<label class="col-sm-4 col-form-label" for="nets">{{'PAGE.K8S.NETS' | translate}}*</label>
<div class="col-sm-8">
<textarea rows="5" cols="50" class="form-control" placeholder="{{'PAGE.K8S.NETSPLACEHOLDER' | translate}}"
@@ -81,22 +89,58 @@
</div>
</div>
</div>
- <div class="form-group row mb-3">
+ <div class="form-group row mb-3" *ngIf="profileType === 'Register'">
<label class="col-sm-4 col-form-label" for="credentials">{{'PAGE.K8S.CREDENTIALS' | translate}}*</label>
<div class="col-sm-8">
- <textarea rows="5" cols="50" class="form-control" placeholder="{{'YAMLCONFIG' | translate}}" formControlName="credentials"
- id="credentials" [ngClass]="{ 'is-invalid': submitted && f.credentials.errors }" required></textarea>
+ <textarea rows="5" cols="50" class="form-control" placeholder="{{'YAMLCONFIG' | translate}}"
+ formControlName="credentials" id="credentials" [ngClass]="{ 'is-invalid': submitted && f.credentials.errors }"
+ required></textarea>
<div class="fileupload-text mt-1 mb-1">{{'FILEUPLOADLABEL' | translate}}</div>
<div class="custom-file">
- <input type="file" #fileInputCredentials class="fileupload custom-file-input" (change)="credentialsFile($event.target.files)"
- id="customFileCredentials">
+ <input type="file" #fileInputCredentials class="fileupload custom-file-input"
+ (change)="credentialsFile($event.target.files)" id="customFileCredentials">
</div>
</div>
</div>
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage'">
+ <label class="col-sm-4 col-form-label" for="k8s_version">{{'PAGE.K8S.REGIONNAME' | translate}}</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.REGIONNAME' | translate}}" type="text"
+ formControlName="region_name" id="k8s_version"
+ [ngClass]="{ 'is-invalid': submitted && f.region_name.errors }">
+ </div>
+ </div>
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage'">
+ <label class="col-sm-4 col-form-label" for="k8s_version">{{'PAGE.K8S.RESOURCEGROUP' | translate}}</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.RESOURCEGROUP' | translate}}" type="text"
+ formControlName="resource_group" id="k8s_version"
+ [ngClass]="{ 'is-invalid': submitted && f.resource_group.errors }">
+ </div>
+ </div>
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage' || profileType === 'scale'">
+ <label class="col-sm-4 col-form-label" for="node_count">{{'PAGE.K8S.NODECOUNT' | translate}}*</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NODECOUNT' | translate}}" type="text"
+ formControlName="node_count" id="node_count" [ngClass]="{ 'is-invalid': submitted && f.node_count.errors }"
+ required>
+ </div>
+ </div>
+ <div class="form-group row mb-3" *ngIf="profileType === 'Manage'">
+ <label class="col-sm-4 col-form-label" for="k8s_version">{{'PAGE.K8S.NODESIZE' | translate}}*</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NODESIZE' | translate}}" type="text"
+ formControlName="node_size" id="k8s_version" [ngClass]="{ 'is-invalid': submitted && f.node_size.errors }"
+ required>
+ </div>
+ </div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
- <button type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
+ <button *ngIf="profileType === 'Manage' || profileType === 'Register'" type="submit"
+ class="btn btn-primary">{{'CREATE' | translate}}</button>
+ <button *ngIf="profileType === 'upgrade' || profileType === 'scale'" type="submit" class="btn btn-primary">{{'APPLY'
+ | translate}}</button>
</div>
</form>
<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.ts b/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.ts
index 8115b6f..bb5dcfa 100644
--- a/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.ts
+++ b/src/app/k8s/k8s-add-cluster/K8sAddClusterComponent.ts
@@ -19,16 +19,17 @@
* @file K8sAddClusterComponent.ts.
*/
import { HttpHeaders } from '@angular/common/http';
-import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
-import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core';
+import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { NotifierService } from 'angular-notifier';
import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
import { environment } from 'environment';
import * as jsyaml from 'js-yaml';
+import { K8SPayload } from 'K8sModel';
import { RestService } from 'RestService';
-import { SharedService, isNullOrUndefined } from 'SharedService';
+import { SharedService } from 'SharedService';
import { VimAccountDetails } from 'VimAccountModel';
/**
* Creating Component
@@ -50,6 +51,12 @@
/** Contains all vim account collections */
public vimAccountSelect: VimAccountDetails;
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileType: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileID: string;
+
/** Contains all deployment methods */
public deploymentMethodsSelect: TYPESECTION[] = [];
@@ -57,7 +64,7 @@
public deploymentMethodsSubmit: Map<string, boolean>;
/** Contains all deployment methods selected */
- public selectedDeploymentMethods: string[] = ['helm-chart', 'helm-chart-v3', 'juju-bundle'];
+ public selectedDeploymentMethods: string[] = ['helm-chart-v3', 'juju-bundle'];
/** Instance for active modal service @public */
public activeModal: NgbActiveModal;
@@ -65,9 +72,15 @@
/** Variable set for twoway bindng @public */
public vimAccountId: string;
+ /** contains url @public */
+ public clusterUrl: string;
+
/** Form submission Add */
public submitted: boolean = false;
+ /** contains payload */
+ public payload: K8SPayload;
+
/** Check the loading results @public */
public isLoadingResults: boolean = false;
@@ -114,10 +127,6 @@
this.sharedService = this.injector.get(SharedService);
this.deploymentMethodsSelect = [
{
- title: 'Helm v2',
- value: 'helm-chart'
- },
- {
title: 'Helm v3',
value: 'helm-chart-v3'
},
@@ -148,7 +157,11 @@
description: ['', [Validators.required]],
nets: ['', [Validators.required]],
deployment_methods: ['', [Validators.required]],
- credentials: ['', [Validators.required]]
+ credentials: ['', [Validators.required]],
+ region_name: [''],
+ resource_group: [''],
+ node_count: ['', [Validators.required]],
+ node_size: ['', [Validators.required]]
});
}
@@ -167,8 +180,57 @@
});
}
+
+ /** Contain selected vimAccount details @public */
+ public getDetailsvim(event: VimAccountDetails): void {
+ this.vimAccountId = event._id;
+ }
+
/** On modal submit k8sAddClusterSubmit will called @public */
public k8sAddClusterSubmit(): void {
+ if (this.profileType === 'Manage') {
+ this.getFormControl('nets').disable();
+ this.getFormControl('credentials').disable();
+ this.getFormControl('deployment_methods').disable();
+ this.manageCluster();
+ } else if (this.profileType === 'Register') {
+ this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/register';
+ this.getFormControl('region_name').disable();
+ this.getFormControl('resource_group').disable();
+ this.getFormControl('node_count').disable();
+ this.getFormControl('node_size').disable();
+ this.registerCluster();
+ } else if (this.profileType === 'upgrade') {
+ this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'upgrade';
+ this.getFormControl('region_name').disable();
+ this.getFormControl('resource_group').disable();
+ this.getFormControl('node_count').disable();
+ this.getFormControl('node_size').disable();
+ this.getFormControl('nets').disable();
+ this.getFormControl('credentials').disable();
+ this.getFormControl('deployment_methods').disable();
+ this.getFormControl('name').disable();
+ this.getFormControl('vim_account').disable();
+ this.getFormControl('description').disable();
+ this.updateCluster();
+ } else if (this.profileType === 'scale') {
+ this.clusterUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'scale';
+ this.getFormControl('region_name').disable();
+ this.getFormControl('resource_group').disable();
+ this.getFormControl('k8s_version').disable();
+ this.getFormControl('node_size').disable();
+ this.getFormControl('nets').disable();
+ this.getFormControl('credentials').disable();
+ this.getFormControl('deployment_methods').disable();
+ this.getFormControl('name').disable();
+ this.getFormControl('vim_account').disable();
+ this.getFormControl('description').disable();
+ this.updateCluster();
+ }
+ }
+
+ /** Register cluster @public */
+ public registerCluster(): void {
this.submitted = true;
this.sharedService.cleanForm(this.k8sclusterForm);
if (this.k8sclusterForm.invalid) {
@@ -177,10 +239,6 @@
const modalData: MODALCLOSERESPONSEDATA = {
message: 'Done'
};
- const apiURLHeader: APIURLHEADER = {
- url: environment.K8SCLUSTER_URL,
- httpOptions: { headers: this.headers }
- };
const validJSONCredentails: boolean = this.sharedService.checkJson(this.k8sclusterForm.value.credentials);
if (validJSONCredentails) {
this.k8sclusterForm.value.credentials = jsyaml.load(this.k8sclusterForm.value.credentials.toString(), { json: true });
@@ -215,11 +273,65 @@
// Transform values to json
this.k8sclusterForm.value.deployment_methods = jsonDMObject;
+ this.k8sclusterForm.value.vim_account = this.vimAccountId;
+
+ const apiURLHeader: APIURLHEADER = {
+ url: this.clusterUrl,
+ httpOptions: { headers: this.headers }
+ };
+
this.isLoadingResults = true;
this.restService.postResource(apiURLHeader, this.k8sclusterForm.value).subscribe((result: {}) => {
this.activeModal.close(modalData);
this.isLoadingResults = false;
this.notifierService.notify('success', this.k8sclusterForm.value.name +
+ this.translateService.instant('PAGE.K8S.REGISTEREDSUCCESSFULLY'));
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Manage cluster @public */
+ public manageCluster(): void {
+ this.submitted = true;
+ this.sharedService.cleanForm(this.k8sclusterForm);
+ if (this.k8sclusterForm.invalid) {
+ return;
+ }
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ const apiURLHeader: APIURLHEADER = {
+ url: environment.K8SCREATECLUSTER_URL,
+ httpOptions: { headers: this.headers }
+ };
+
+ this.isLoadingResults = true;
+ const payload: K8SPayload = {
+ name: this.k8sclusterForm.value.name,
+ vim_account: this.k8sclusterForm.value.vim_account,
+ location: this.k8sclusterForm.value.location,
+ region_name: this.k8sclusterForm.value.region_name,
+ resource_group: this.k8sclusterForm.value.resource_group,
+ k8s_version: this.k8sclusterForm.value.k8s_version,
+ node_size: this.k8sclusterForm.value.node_size,
+ node_count: Number(this.k8sclusterForm.value.node_count),
+ description: this.k8sclusterForm.value.description
+ };
+ if (this.k8sclusterForm.value.region_name === '') {
+ delete payload.region_name;
+ } else if (this.k8sclusterForm.value.resource_group === '') {
+ delete payload.resource_group;
+ }
+ if (this.k8sclusterForm.value.region_name === '' && this.k8sclusterForm.value.resource_group === '') {
+ delete payload.region_name;
+ delete payload.resource_group;
+ }
+ this.restService.postResource(apiURLHeader, payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ this.notifierService.notify('success', this.k8sclusterForm.value.name +
this.translateService.instant('PAGE.K8S.CREATEDSUCCESSFULLY'));
}, (error: ERRORDATA) => {
this.restService.handleError(error, 'post');
@@ -227,6 +339,42 @@
});
}
+ /** Update cluster @public */
+ public updateCluster(): void {
+ this.submitted = true;
+ this.sharedService.cleanForm(this.k8sclusterForm);
+ if (this.k8sclusterForm.invalid) {
+ return;
+ }
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ const apiURLHeader: APIURLHEADER = {
+ url: this.clusterUrl,
+ httpOptions: { headers: this.headers }
+ };
+
+ this.isLoadingResults = true;
+ if (this.profileType === 'upgrade') {
+ this.payload = {
+ k8s_version: this.k8sclusterForm.value.k8s_version
+ };
+ } else if (this.profileType === 'scale') {
+ this.payload = {
+ node_count: this.k8sclusterForm.value.node_count
+ };
+ }
+ this.restService.postResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.UPDATEDSUCCESSFULLY'));
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ this.isLoadingResults = false;
+ });
+ }
+
/** Nets file process @private */
public netsFile(files: FileList): void {
if (files && files.length === 1) {
@@ -270,4 +418,10 @@
this.fileInputCredentialsLabel.nativeElement.innerText = files[0].name;
this.fileInputCredentials.nativeElement.value = null;
}
+
+ /** Used to get the AbstractControl of controlName passed @private */
+ private getFormControl(controlName: string): AbstractControl {
+ // eslint-disable-next-line security/detect-object-injection
+ return this.k8sclusterForm.controls[controlName];
+ }
}
diff --git a/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.html b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.html
new file mode 100644
index 0000000..c12c4c0
--- /dev/null
+++ b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.html
@@ -0,0 +1,73 @@
+<!--
+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="modal-header">
+ <h4 class="modal-title" id="modal-basic-title">{{'PAGE.K8S.ATTACHDETATCHPROFILE' | translate}}</h4>
+ <button class="button-xs" type="button" class="close" aria-label="Close" (click)="activeModal.close()">
+ <i class="fas fa-times-circle text-danger"></i>
+ </button>
+</div>
+<form [formGroup]="attachForm" (ngSubmit)="attachProfile()">
+ <div class="modal-body" *ngIf="checkDetails" formArrayName="infra_config_profiles">
+ <div class="form-group row p-2 bg-light text-white projects-roles-head text-white justify-content-end">
+ <div class="col-4">
+ <button [disabled]="isAttach" type="button" class="btn btn-primary" (click)="addMapping()">
+ <i class="fas fa-plus-circle"></i> {{'PAGE.K8S.ATTACHPROFILE' | translate}}</button>
+ </div>
+ </div>
+ <label class="col-sm-12 col-form-label mandatory-label ps-2"
+ [ngClass]="{'text-danger': attachForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
+ translate}}</label>
+ <div *ngFor="let params of getControls(); let i = index;" [formGroupName]="i">
+ <div class="card bg-light">
+ <div class="card-body">
+ <div class="form-group row">
+ <label class="col-sm-3 col-md-3 col-form-label" for="profile_name_{{i}}">{{'PAGE.K8S.PROFILE' |
+ translate}}*</label>
+ <div class="col-sm-8 col-md-8">
+ <ng-select placeholder="{{'SELECT' | translate}}" [items]="userDetails" bindLabel="name"
+ bindValue="_id" formControlName="profile_name" id="profile_name_{{i}}"
+ [ngClass]="{ 'is-invalid': submitted && params.controls.profile_name.errors }">
+ <ng-option *ngFor="let option of userDetails" [value]="option._id">{{ option.name }}</ng-option>
+ </ng-select>
+ </div>
+ <div class="col-sm-1"
+ *ngIf="profileDetails.infra_config_profiles[i] ? profileDetails.infra_config_profiles[i].profile_name === '' : true">
+ <button class="button-xs" type="button" class="delete" (click)="removeMapping(i)"
+ placement="right" ngbTooltip="{{ 'CANCEL' | translate }}">
+ <i class="fas fa-minus-circle text-danger"></i>
+ </button>
+ </div>
+ <div class="col-sm-1"
+ *ngIf="profileDetails.infra_config_profiles[i] ? profileDetails.infra_config_profiles[i].profile_name !== '' : false">
+ <button class="button-xs" type="button" class="delete"
+ (click)="deleteProfile(profileDetails.infra_config_profiles[i])"
+ placement="right" ngbTooltip="{{ 'PAGE.K8S.DETATCH' | translate }}">
+ <i class="fas fa-trash-alt text-danger"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
+ <button type="submit" class="btn btn-primary">{{'APPLY' | translate}}</button>
+ </div>
+</form>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.scss b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.scss
new file mode 100644
index 0000000..0f5abee
--- /dev/null
+++ b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.scss
@@ -0,0 +1,49 @@
+/*
+ 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)
+*/
+.card{
+ border-radius: 15px;
+ width: auto;
+ height: auto;
+ margin-bottom: 5px;
+ }
+
+ .card-body{
+ flex: 1 1 auto;
+ min-height: 1px;
+ padding: 5px;
+ }
+
+ .form-group{
+ margin-bottom: 1px;
+ }
+
+ .col-sm-1{
+ position: relative;
+ bottom: 10px;
+ }
+ .modal-body .row{
+ margin-bottom: 0px;
+ }
+ .delete{
+ position: absolute;
+ top: 10px !important;
+ left: 3px;
+ border: 0;
+ font-size: 1.3125rem;
+ background-color: transparent;
+ }
\ No newline at end of file
diff --git a/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.ts b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.ts
new file mode 100644
index 0000000..dcbe4ee
--- /dev/null
+++ b/src/app/k8s/k8s-attach-detatch-profile/K8sAttachProfileComponent.ts
@@ -0,0 +1,321 @@
+/*
+ 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 Attach Profile Component.
+ */
+import { HttpHeaders } from '@angular/common/http';
+import { ChangeDetectorRef, Component, Injector, Input, OnInit } from '@angular/core';
+import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { NotifierService } from 'angular-notifier';
+import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { environment } from 'environment';
+import { K8SCreateCLUSTERDATA, K8SPayload, ProfileMap, ProfileMappings } from 'K8sModel';
+import { RestService } from 'RestService';
+/**
+ * Creating Component
+ * @Component takes K8sAttachProfileComponent.html as template url
+ */
+@Component({
+ selector: 'app-k8s-attach-profile',
+ templateUrl: './K8sAttachProfileComponent.html',
+ styleUrls: ['./K8sAttachProfileComponent.scss']
+})
+/** Exporting a class @exports K8sAttachProfileComponent */
+export class K8sAttachProfileComponent implements OnInit {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** Instance for active modal service @public */
+ public activeModal: NgbActiveModal;
+
+ /** FormGroup user Edit Account added to the form @ html @public */
+ public attachForm: FormGroup;
+
+ /** Form submission Add */
+ public submitted: boolean = false;
+
+ /** Form submission Add */
+ public selectedData: string;
+
+ /** Input contains Modal dialog component Instance @private */
+ @Input() public userTitle: string;
+
+ /** Input contains Modal dialog component Instance @private */
+ @Input() public userID: string;
+
+ /** Contains user details information @public */
+ public userDetails: K8SCreateCLUSTERDATA[];
+
+ /** Contains user details information @public */
+ public filterDetails: K8SCreateCLUSTERDATA[];
+
+ /** Contains user details information @public */
+ public checkDetails: K8SCreateCLUSTERDATA[];
+
+ /** Contains user details information @public */
+ public profileDetails: K8SCreateCLUSTERDATA;
+
+ /** Contains user details information @public */
+ public count: number;
+
+ /** Profile Mapping @public */
+ public profileMap: ProfileMap = {};
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = false;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileType: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileID: string;
+
+ /** Give the message for the loading @public */
+ public profileUrl: string;
+
+ /** Give the message for the loading @public */
+ public isAttach: boolean = false;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** FormBuilder instance added to the formBuilder @private */
+ private formBuilder: FormBuilder;
+
+ /** Controls the header form @private */
+ private headers: HttpHeaders;
+
+ /** Notifier service to popup notification @private */
+ private notifierService: NotifierService;
+
+ /** Contains tranlsate instance @private */
+ private translateService: TranslateService;
+
+ /** Profile Form array @private */
+ private attachFormArray: FormArray;
+
+ /** Detect changes for the User Input */
+ private cd: ChangeDetectorRef;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.formBuilder = this.injector.get(FormBuilder);
+ this.restService = this.injector.get(RestService);
+ this.activeModal = this.injector.get(NgbActiveModal);
+ this.notifierService = this.injector.get(NotifierService);
+ this.translateService = this.injector.get(TranslateService);
+ this.cd = this.injector.get(ChangeDetectorRef);
+ }
+
+ /** Generate primitive params @public */
+ get profileParamsBuilder(): FormGroup {
+ return this.formBuilder.group({
+ profile_name: [null, [Validators.required]]
+ });
+ }
+
+ /** convenience getter for easy access to form fields */
+ get f(): FormGroup['controls'] { return this.attachForm.controls; }
+
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.headers = new HttpHeaders({
+ 'Content-Type': 'application/json',
+ Accept: 'application/json',
+ 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
+ });
+ this.initializeForm();
+ this.generateData();
+ this.generateProfile();
+ }
+
+ /** Initializing Form Action @public */
+ public initializeForm(): void {
+ this.attachForm = this.formBuilder.group({
+ infra_config_profiles: this.formBuilder.array([])
+ });
+ }
+
+ /** Handle FormArray Controls @public */
+ public getControls(): AbstractControl[] {
+ return (this.attachForm.get('infra_config_profiles') as FormArray).controls;
+ }
+
+ /** Fetching the data from server to Load in the smarttable @public */
+ public generateData(): void {
+ if (this.profileID !== '') {
+ this.isLoadingResults = true;
+ if (this.profileType === 'infra-config') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_config_profiles';
+ } else if (this.profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_controller_profiles';
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'app_profiles';
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'resource_profiles';
+ }
+ this.restService.getResource(this.profileUrl).subscribe((userDetail: K8SCreateCLUSTERDATA[]): void => {
+ this.checkDetails = userDetail;
+ this.filterDetails = this.checkDetails.filter((itemData: K8SCreateCLUSTERDATA): boolean => itemData.default === false);
+ if (this.filterDetails.length !== 0) {
+ this.filterDetails.forEach((datas: K8SCreateCLUSTERDATA): void => {
+ let profileData: ProfileMappings[] = [];
+ profileData = this.filterDetails.map((item) => ({
+ name: item.name,
+ _id: item._id
+ }));
+ this.profileDetails = { infra_config_profiles: profileData };
+ });
+ this.count = this.profileDetails.infra_config_profiles.length;
+ this.loadMapping();
+ } else {
+ this.profileDetails = { infra_config_profiles: [] };
+ }
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA): void => {
+ this.isLoadingResults = false;
+ this.restService.handleError(error, 'get');
+ });
+ }
+ }
+
+ /** Fetching the data from server to Load in the smarttable @public */
+ public generateProfile(): void {
+ this.isLoadingResults = true;
+ if (this.profileType === 'infra-config') {
+ this.profileUrl = environment.K8SINFRACONFIGPROFILE_URL;
+ } else if (this.profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SINFRACONTROLLERPROFILE_URL;
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SAPPPROFILE_URL;
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SRESOURCEPROFILE_URL;
+ }
+ this.restService.getResource(this.profileUrl).subscribe((userDetail: K8SCreateCLUSTERDATA[]): void => {
+ this.userDetails = userDetail.filter((itemData: K8SCreateCLUSTERDATA): boolean => itemData.default === false);
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA): void => {
+ this.isLoadingResults = false;
+ this.restService.handleError(error, 'get');
+ });
+ }
+
+ /** Set all profile values to the form @public */
+ public loadMapping(): void {
+ this.profileDetails.infra_config_profiles.forEach((datas: ProfileMappings): void => {
+ this.attachFormArray = this.attachForm.get('infra_config_profiles') as FormArray;
+ const control = this.formBuilder.group({
+ profile_name: [datas._id]
+ });
+ this.attachFormArray.push(control);
+ });
+ }
+
+ /** Remove profile from the list @public */
+ public removeMapping(index: number): void {
+ this.attachFormArray.removeAt(index);
+ this.isAttach = false;
+ }
+
+ /** Submit profile @public */
+ public attachProfile(): void {
+ this.submitted = true;
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ if (this.attachForm.invalid) { return; }
+ if (this.profileType === 'infra-config') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_config_profiles';
+ } else if (this.profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_controller_profiles';
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'app_profiles';
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'resource_profiles';
+ }
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl
+ };
+ this.profileMap.add_profile = [];
+ this.attachForm.value.infra_config_profiles.forEach((res: ProfileMappings): void => {
+ this.profileMap.add_profile.push({ id: res.profile_name });
+ });
+ this.profileMap.add_profile.splice(0, this.count);
+ if (this.profileMap.add_profile.length !== 0) {
+ if (!this.attachForm.dirty) {
+ this.notifierService.notify('warning', this.translateService.instant('PAGE.TOPOLOGY.DATAEMPTY'));
+ return;
+ }
+ this.isLoadingResults = true;
+ this.restService.patchResource(apiURLHeader, this.profileMap).subscribe((result: {}): void => {
+ this.isLoadingResults = false;
+ this.activeModal.close(modalData);
+ this.notifierService.notify('success', this.translateService.instant('PAGE.K8S.ATTACHEDSUCCESSFULLY'));
+ }, (error: ERRORDATA): void => {
+ this.isLoadingResults = false;
+ this.restService.handleError(error, 'patch');
+ });
+ } else {
+ this.notifierService.notify('error', this.translateService.instant('PAGE.K8S.WARNING'));
+ }
+ }
+
+ /** Add extra mapping and set empty profile @public */
+ public addMapping(): void {
+ this.attachFormArray = this.attachForm.get('infra_config_profiles') as FormArray;
+ this.attachFormArray.push(this.profileParamsBuilder);
+ if ((this.attachFormArray.value.length === this.count + 1) || (this.attachFormArray.value.length === 1)) {
+ this.isAttach = true;
+ }
+ }
+
+ /** Remove profile @public */
+ public deleteProfile(getProfile: ProfileMappings): void {
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ const removeProfile: ProfileMap = { remove_profile: [] };
+ removeProfile.remove_profile = [{ id: getProfile._id }];
+ if (this.profileType === 'infra-config') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_config_profiles';
+ } else if (this.profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'infra_controller_profiles';
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'app_profiles';
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SCREATECLUSTER_URL + '/' + this.profileID + '/' + 'resource_profiles';
+ }
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl
+ };
+ this.isLoadingResults = true;
+ this.restService.patchResource(apiURLHeader, removeProfile).subscribe((result: {}): void => {
+ this.isLoadingResults = false;
+ this.activeModal.close(modalData);
+ this.notifierService.notify('success', this.translateService.instant('PAGE.K8S.DETATCHEDSUCCESSFULLY'));
+ }, (error: ERRORDATA): void => {
+ this.isLoadingResults = false;
+ this.restService.handleError(error, 'patch');
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html
new file mode 100644
index 0000000..e75cc7e
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.html
@@ -0,0 +1,126 @@
+<!--
+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)
+-->
+<form [formGroup]="KsuForm" (ngSubmit)="KSUAddSubmit();">
+ <div class="modal-header">
+ <h4 *ngIf="profileType === 'add'" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.ADDKSU' | translate}}</h4>
+ <h4 *ngIf="profileType === 'edit'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.EDITKSU' | translate}}</h4>
+ <h4 *ngIf="profileType === 'move'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.MOVE' | translate}}</h4>
+ <h4 *ngIf="profileType === 'clone'"class="modal-title" id="modal-basic-title">{{'PAGE.K8S.CLONE' | translate}}</h4>
+ <button class="button-xs" type="button" class="close" aria-label="Close" (click)="activeModal.close()">
+ <i class="fas fa-times-circle text-danger"></i>
+ </button>
+ </div>
+ <div class="modal-body modal-body-custom-height">
+ <div class="form-group row mb-3" *ngIf="isClone || isKsu">
+ <label class="col-sm-12 col-form-label mandatory-label"
+ [ngClass]="{'text-danger': KsuForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
+ translate}}</label>
+ <label class="col-sm-4 col-form-label" for="name">{{'PAGE.K8S.NAME' | translate}}*</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NAME' | translate}}" type="text"
+ formControlName="name" id="name" [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
+ </div>
+ </div>
+ <div class="form-group row mb-3"*ngIf="isKsu">
+ <label class="col-sm-4 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}*</label>
+ <div class="col-sm-8">
+ <textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
+ formControlName="description" id="description"
+ [ngClass]="{ 'is-invalid': submitted && f.description.errors }" required></textarea>
+ </div>
+ </div>
+ <div class="form-group row mb-3" *ngIf="isClone || isMove || isKsu">
+ <label class="col-sm-4 col-form-label" for="profile_type">{{'PAGE.K8S.PROFILETYPE' | translate}}*</label>
+ <div class="col-sm-8">
+ <ng-select (change)="getprofileDetails($event.value)"
+ placeholder="{{'SELECT' | translate}} {{'TYPE' | translate}}" [items]="profileSelect"
+ bindLabel="title" bindValue="value" formControlName="profile_type" id="profile_type"
+ [ngClass]="{ 'is-invalid': submitted && f.profile_type.errors }" required>
+ </ng-select>
+ </div>
+ </div>
+ <div class="form-group row mb-3" *ngIf="isClone || isMove || isKsu">
+ <label class="col-sm-4 col-form-label" for="id">{{'PAGE.K8S.PROFILENAME' | translate}}*</label>
+ <div class="col-sm-8">
+ <ng-select placeholder=" {{'SELECT' | translate}} {{'NAME' |
+ translate}}" [items]="profileDetails" bindLabel="name" bindValue="id" formControlName="id" id="id"
+ [ngClass]="{ 'is-invalid': submitted && f.id.errors }" required>
+ </ng-select>
+ </div>
+ </div>
+ <div class="form-group row p-2 bg-light text-white justify-content-end mb-3"*ngIf="isKsu">
+ <div class="col-4">
+ <button class="button-xs" type="button" class="btn btn-primary" (click)="addOka()">
+ <i class="fas fa-plus-circle"></i>{{'PAGE.K8S.SELECTOKA' | translate}}</button>
+ </div>
+ </div>
+ <ng-container *ngIf="isKsu">
+ <div formArrayName="oka" *ngFor="let params of getControls(); let i = index;">
+ <div class="form-group row" [formGroupName]="i">
+ <div class="card bg-light">
+ <div class="card-body">
+ <div class="form-group row">
+ <label class="col-sm-3 col-md-3 col-form-label" for="_id{{i}}">{{'PAGE.K8S.OKA' |
+ translate}}</label>
+ <div class="col-sm-8 col-md-8">
+ <ng-select
+ placeholder="{{'SELECT' | translate}} {{'PAGE.K8S.OKANAME' | translate}}" [items]="okaDetail" bindLabel="name"
+ bindValue="id" formControlName="_id" id="_id{{i}}"
+ [ngClass]="{ 'is-invalid': submitted && params.controls._id.errors }">
+ </ng-select>
+ <div class="fileupload-text mt-1 mb-1">or {{'PAGE.K8S.PATH' | translate}}</div>
+ <div class="col-sm-8 col-md-8">
+ <input autocomplete="off" class="form-control"
+ placeholder="{{'PAGE.K8S.PATH' | translate}}" type="text" formControlName="sw_catalog_path"
+ id="sw_catalog_path" [ngClass]="{ 'is-invalid': submitted && params.controls.sw_catalog_path.errors }">
+ </div>
+ </div>
+ <label class="col-sm-3 col-md-3 col-form-label"
+ for="transformation{{i}}">{{'PAGE.K8S.TRANSFORMFILE' |
+ translate}}</label>
+ <div class="col-sm-8 col-md-8">
+ <textarea rows="5" cols="50" class="form-control" placeholder="{{'YAMLCONFIG' | translate}}"
+ formControlName="transformation" id="transformation"></textarea>
+ <div class="fileupload-text mt-1 mb-1">{{'FILEUPLOADLABEL' | translate}}</div>
+ <div class="custom-file">
+ <input type="file" #fileInputConfig class="fileupload custom-file-input"
+ (change)="configFile($event.target.files)" id="customConfigFile">
+ </div>
+ </div>
+ <div class="col-sm-1">
+ <button class="button-xs" type="button" class="close" (click)="removeMapping(i)"
+ placement="right" ngbTooltip="{{ 'CANCEL' | translate }}">
+ <i class="fas fa-minus-circle text-danger"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </ng-container>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
+ <button *ngIf="profileType === 'add'" type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
+ <button *ngIf="profileType === 'edit'" type="submit" class="btn btn-primary">{{'Edit' | translate}}</button>
+ <button *ngIf="profileType === 'move'" type="submit" class="btn btn-primary">{{'Move' | translate}}</button>
+ <button *ngIf="profileType === 'clone'" type="submit" class="btn btn-primary">{{'Clone' | translate}}</button>
+ </div>
+</form>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.scss b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts
new file mode 100644
index 0000000..26f86f1
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-add/KSUAddComponent.ts
@@ -0,0 +1,481 @@
+/*
+ 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 KSUAddComponent.ts.
+ */
+import { HttpHeaders } from '@angular/common/http';
+import { Component, ElementRef, Injector, Input, OnInit, ViewChild } from '@angular/core';
+import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { NotifierService } from 'angular-notifier';
+import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION, URLPARAMS } from 'CommonModel';
+import { environment } from 'environment';
+import * as jsyaml from 'js-yaml';
+import { INFRACONFIGPAYLOAD, KSU, OKA } from 'K8sModel';
+import { RestService } from 'RestService';
+import { isNullOrUndefined, SharedService } from 'SharedService';
+/**
+ * Creating Component
+ * @Component takes KSUAddComponent.html as template url
+ */
+@Component({
+ selector: 'app-ksu-add',
+ templateUrl: './KSUAddComponent.html',
+ styleUrls: ['./KSUAddComponent.scss']
+})
+/** Exporting a class @exports KSUAddComponent */
+export class KSUAddComponent implements OnInit {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** FormGroup instance added to the form @ html @public */
+ public KsuForm: FormGroup;
+
+ /** Contains all deployment methods */
+ public profileSelect: TYPESECTION[] = [];
+
+ /** Instance for active modal service @public */
+ public activeModal: NgbActiveModal;
+
+ /** Form submission Add */
+ public submitted: boolean = false;
+
+ /** check move action */
+ public isMove: boolean = false;
+
+ /** check clone action */
+ public isClone: boolean = false;
+
+ /** check KSU */
+ public isKsu: boolean = false;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = false;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** contains url @public */
+ public profileUrl: string;
+
+ /** contains profileData @public */
+ public profileData: {}[] = [];
+
+ /** OKA array @private */
+ private okaArray: FormArray;
+
+ /** contains profile details @public */
+ public profileDetails: {}[];
+
+ /** contains Oka Data @public */
+ public okaData: {}[] = [];
+
+ /** contains OKA details @public */
+ public okaDetail: {}[];
+
+ /** contains payload @public */
+ public payload: INFRACONFIGPAYLOAD | KSU;
+
+ /** oka Form array @private */
+ private okaFormArray: FormArray;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileType: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileID: string;
+
+ /** Element ref for fileInputConfig @public */
+ @ViewChild('fileInputConfig') fileInputConfig: ElementRef<HTMLInputElement>;
+
+ /** Element ref for fileInputConfigLabel @public */
+ @ViewChild('fileInputConfigLabel') fileInputConfigLabel: ElementRef<HTMLLabelElement>;
+
+ /** FormBuilder instance added to the formBuilder @private */
+ private formBuilder: FormBuilder;
+
+ /** Utilizes rest service for any CRUD operations @private */
+ private restService: RestService;
+
+ /** Notifier service to popup notification @private */
+ private notifierService: NotifierService;
+
+ /** Contains tranlsate instance @private */
+ private translateService: TranslateService;
+
+ /** Controls the header form @private */
+ private headers: HttpHeaders;
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.activeModal = this.injector.get(NgbActiveModal);
+ this.formBuilder = this.injector.get(FormBuilder);
+ this.notifierService = this.injector.get(NotifierService);
+ this.translateService = this.injector.get(TranslateService);
+ this.sharedService = this.injector.get(SharedService);
+ this.profileSelect = [
+ {
+ title: 'Infra Config Profile',
+ value: 'infra_config_profiles'
+ },
+ {
+ title: 'Infra Controller Profile',
+ value: 'infra_controller_profiles'
+ }, {
+ title: 'App Profile',
+ value: 'app_profiles'
+ }, {
+ title: 'Resource Profile',
+ value: 'resource_profiles'
+ }
+ ];
+ }
+
+ public ngOnInit(): void {
+ /** On Initializing call the methods */
+ this.KsuFormAction();
+ this.headers = new HttpHeaders({
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
+ });
+ this.okaDetails();
+ if (this.profileType === 'clone') {
+ this.isClone = true;
+ } else if (this.profileType === 'move') {
+ this.isMove = true;
+ } else if (this.profileType === 'edit') {
+ this.isKsu = true;
+ this.getksuDetails();
+ } else {
+ this.isKsu = true;
+ }
+ }
+
+ /** Generate primitive params @public */
+ get okaParamsBuilder(): FormGroup {
+ return this.formBuilder.group({
+ _id: [null],
+ sw_catalog_path: [null],
+ transformation: [null]
+ });
+ }
+
+
+ /** On modal initializing forms @public */
+ public KsuFormAction(): void {
+ this.KsuForm = this.formBuilder.group({
+ name: ['', [Validators.required]],
+ description: ['', [Validators.required]],
+ profile_type: [null, [Validators.required]],
+ id: [null, [Validators.required]],
+ oka: this.formBuilder.array([])
+ });
+ }
+
+ /** Handle FormArray Controls @public */
+ public getControls(): AbstractControl[] {
+ return (this.KsuForm.get('oka') as FormArray).controls;
+ }
+
+ /** convenience getter for easy access to form fields */
+ get f(): FormGroup['controls'] { return this.KsuForm.controls; }
+
+ /** Get OKA details @public */
+ public okaDetails(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.OKAPACKAGES_URL)
+ .subscribe((okaData: []): void => {
+ okaData.forEach((okaDetail: INFRACONFIGPAYLOAD): void => {
+ const oka: {} = {
+ name: okaDetail.name,
+ id: okaDetail._id
+ };
+ this.okaData.push(oka);
+ });
+ this.okaDetail = this.okaData;
+ this.isLoadingResults = false;
+ }, (error: ERRORDATA): void => {
+ this.isLoadingResults = false;
+ this.restService.handleError(error, 'get');
+ });
+ }
+
+ /** Get KSU details @public */
+ public getksuDetails(): void {
+ this.restService.getResource(environment.KSU_URL + '/' + this.profileID)
+ .subscribe((ksuData: KSU): void => {
+ this.KsuForm.patchValue({ id: ksuData.profile._id, name: ksuData.name, description: ksuData.description, profile_type: ksuData.profile.profile_type });
+ this.getprofileDetails(this.KsuForm.value.profile_type, ksuData.profile.name);
+ ksuData.oka.forEach((data: OKA): void => {
+ this.okaArray = this.KsuForm.get('oka') as FormArray;
+ const transformations: string = JSON.stringify(data.transformation);
+ if (!isNullOrUndefined(data._id)) {
+ data.sw_catalog_path = null;
+ } else if (!isNullOrUndefined(data.sw_catalog_path)) {
+ data._id = null;
+ }
+ const okaFormGroup = this.formBuilder.group({
+ _id: data._id,
+ sw_catalog_path: data.sw_catalog_path,
+ transformation: transformations
+ });
+ this.okaArray.push(okaFormGroup);
+ });
+ }, (error: ERRORDATA): void => {
+ this.restService.handleError(error, 'get');
+ });
+ }
+
+
+ /** On modal submit ksuAddSubmit will called @public */
+ public KSUAddSubmit(): void {
+ if (this.profileType === 'move') {
+ this.profileUrl = environment.KSU_URL + '/' + this.profileID + '/move';
+ this.payload = {
+ profile: {
+ _id: this.KsuForm.value.id,
+ profile_type: this.KsuForm.value.profile_type
+ }
+ };
+ this.getFormControl('description').disable();
+ this.getFormControl('oka').disable();
+ this.getFormControl('name').disable();
+ } else if (this.profileType === 'clone') {
+ this.getFormControl('description').disable();
+ this.getFormControl('oka').disable();
+ this.profileUrl = environment.KSU_URL + '/' + this.profileID + '/clone';
+ this.payload = {
+ name: this.KsuForm.value.name,
+ profile: {
+ _id: this.KsuForm.value.id,
+ profile_type: this.KsuForm.value.profile_type
+ }
+ };
+ } else if (this.profileType === 'edit' || this.profileType === 'add') {
+ this.addEditKSU();
+ }
+ this.submitted = true;
+ this.sharedService.cleanForm(this.KsuForm);
+ if (this.KsuForm.invalid) {
+ return;
+ }
+ if (this.profileType === 'edit') {
+ this.editKSU();
+ } else {
+ this.addKSU();
+ }
+ }
+
+ /** Add/Edit KSU @public */
+ public addEditKSU(): void {
+ this.okaArray = this.KsuForm.get('oka') as FormArray;
+ const transValue = this.okaArray.at(0).get('transformation').value;
+ const validJSON: boolean = this.sharedService.checkJson(transValue);
+ if (validJSON) {
+ for (let i = 0; i < this.okaArray.length; i++) {
+ const formGroup = this.okaArray.at(i) as FormGroup;
+ formGroup.patchValue({
+ transformation: JSON.parse(transValue)
+ });
+ }
+ } else {
+ const getConfigJson: string = jsyaml.load(transValue, { json: true });
+ for (let i = 0; i < this.okaArray.length; i++) {
+ const formGroup = this.okaArray.at(i) as FormGroup;
+ formGroup.patchValue({
+ transformation: JSON.parse(getConfigJson)
+ });
+ }
+ }
+ if (this.profileType === 'edit') {
+ this.profileUrl = environment.KSU_URL + '/' + this.profileID;
+ this.payload = {
+ name: this.KsuForm.value.name,
+ description: this.KsuForm.value.description,
+ profile: {
+ _id: this.KsuForm.value.id,
+ sw_catalog_path: this.KsuForm.value.sw_catalog_path,
+ profile_type: this.KsuForm.value.profile_type
+ },
+ oka: this.KsuForm.value.oka
+ };
+ } else {
+ this.profileUrl = environment.KSU_URL;
+ this.payload = {
+ ksus: [{
+ name: this.KsuForm.value.name,
+ description: this.KsuForm.value.description,
+ profile: {
+ _id: this.KsuForm.value.id,
+ sw_catalog_path: this.KsuForm.value.sw_catalog_path,
+ profile_type: this.KsuForm.value.profile_type
+ },
+ oka: this.KsuForm.value.oka
+ }]
+ };
+ }
+ }
+ /** Add/move/clone KSU @public */
+ public addKSU(): void {
+ this.isLoadingResults = true;
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl,
+ httpOptions: { headers: this.headers }
+ };
+ this.restService.postResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ if (this.profileType === 'move') {
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.MOVEDSUCCESSFULLY'));
+ } else if (this.profileType === 'clone') {
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.CLONEDSUCCESSFULLY'));
+ } else {
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.KSUCREATEDSUCCESSFULLY'));
+ }
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ if (error.error.status === 422 || error.error.status === 400) {
+ this.activeModal.close(modalData);
+ }
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Edit KSU @public */
+ public editKSU(): void {
+ this.isLoadingResults = true;
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl,
+ httpOptions: { headers: this.headers }
+ };
+ this.restService.patchResource(apiURLHeader, this.payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.KSUEDITEDSUCCESSFULLY'));
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ if (error.error.status === 422 || error.error.status === 400) {
+ this.activeModal.close(modalData);
+ }
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Config file process @private */
+ public configFile(files: FileList): void {
+ if (files && files.length === 1) {
+ const fileFormat: string = this.sharedService.fetchFileExtension(files).toLocaleLowerCase();
+ if (fileFormat === 'yaml' || fileFormat === 'yml') {
+ this.sharedService.getFileString(files, 'yaml').then((fileContent: string): void => {
+ this.okaArray = this.KsuForm.get('oka') as FormArray;
+ for (let i = 0; i < this.okaArray.length; i++) {
+ const formGroup = this.okaArray.at(i) as FormGroup;
+ formGroup.patchValue({
+ transformation: fileContent // Set the value for the specified key
+ });
+ }
+ }).catch((err: string): void => {
+ if (err === 'typeError') {
+ this.notifierService.notify('error', this.translateService.instant('YAMLFILETYPEERRROR'));
+ } else {
+ this.notifierService.notify('error', this.translateService.instant('ERROR'));
+ }
+ this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
+ this.fileInputConfig.nativeElement.value = null;
+ });
+ } else if (fileFormat === 'json') {
+ this.sharedService.getFileString(files, 'json').then((fileContent: string): void => {
+ const getConfigJson: string = jsyaml.load(fileContent, { json: true });
+ this.KsuForm.get('transformation').setValue(JSON.stringify(getConfigJson));
+ }).catch((err: string): void => {
+ if (err === 'typeError') {
+ this.notifierService.notify('error', this.translateService.instant('JSONFILETYPEERRROR'));
+ } else {
+ this.notifierService.notify('error', this.translateService.instant('ERROR'));
+ }
+ this.fileInputConfigLabel.nativeElement.innerText = this.translateService.instant('CHOOSEFILE');
+ this.fileInputConfig.nativeElement.value = null;
+ });
+ }
+ } else if (files && files.length > 1) {
+ this.notifierService.notify('error', this.translateService.instant('DROPFILESVALIDATION'));
+ }
+ this.fileInputConfigLabel.nativeElement.innerText = files[0].name;
+ this.fileInputConfig.nativeElement.value = null;
+ }
+ /** Add OKA @public */
+ public addOka(): void {
+ this.okaFormArray = this.KsuForm.get('oka') as FormArray;
+ this.okaFormArray.push(this.okaParamsBuilder);
+ }
+
+ /** Remove OKA @public */
+ public removeMapping(index: number): void {
+ this.okaFormArray.removeAt(index);
+ }
+
+ /** Get profile details @public */
+ public getprofileDetails(event: string, name?: string): void {
+ this.profileData = [];
+ if (event === 'infra_config_profiles') {
+ this.profileUrl = environment.K8SINFRACONFIGPROFILE_URL;
+ } else if (event === 'infra_controller_profiles') {
+ this.profileUrl = environment.K8SINFRACONTROLLERPROFILE_URL;
+ } else if (event === 'app_profiles') {
+ this.profileUrl = environment.K8SAPPPROFILE_URL;
+ } else if (event === 'resource_profiles') {
+ this.profileUrl = environment.K8SRESOURCEPROFILE_URL;
+ }
+ this.restService.getResource(this.profileUrl)
+ .subscribe((profileData: []): void => {
+ profileData.forEach((profileDetail: INFRACONFIGPAYLOAD): void => {
+ const profile: {} = {
+ name: profileDetail.name,
+ id: profileDetail._id
+ };
+ this.profileData.push(profile);
+ });
+ this.profileDetails = this.profileData;
+ }, (error: ERRORDATA): void => {
+ this.restService.handleError(error, 'get');
+ });
+ }
+ /** Used to get the AbstractControl of controlName passed @private */
+ private getFormControl(controlName: string): AbstractControl {
+ // eslint-disable-next-line security/detect-object-injection
+ return this.KsuForm.controls[controlName];
+ }
+}
diff --git a/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html
new file mode 100644
index 0000000..de83ac5
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.html
@@ -0,0 +1,45 @@
+<!--
+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="d-flex align-items-center header-style">{{'PAGE.K8S.KSU' | translate}}</div>
+ <span class="button">
+ <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Profile' | translate}}" (click)="addKSU()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.ADDKSU' | translate}}
+ </button>
+ </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+ <div class="col-auto me-auto">
+ <nav class="custom-items-config">
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+ </nav>
+ </div>
+ <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+ <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
+ </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.scss b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts
new file mode 100644
index 0000000..2591b4c
--- /dev/null
+++ b/src/app/k8s/k8s-ksu/ksu-details/KSUComponent.ts
@@ -0,0 +1,254 @@
+/*
+ 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 KSUComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { KSUAddComponent } from '../ksu-add/KSUAddComponent';
+/**
+ * Creating Component
+ * @Component takes KSUComponent.html as template url
+ */
+@Component({
+ selector: 'app-ksu-details',
+ templateUrl: './KSUComponent.html',
+ styleUrls: ['./KSUComponent.scss']
+})
+/** Exporting a class @exports KSUComponent */
+export class KSUComponent implements OnInit, OnDestroy {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** handle translate @public */
+ public translateService: TranslateService;
+
+ /** Data of smarttable populate through LocalDataSource @public */
+ public dataSource: LocalDataSource = new LocalDataSource();
+
+ /** Columns list of the smart table @public */
+ public columnList: object = {};
+
+ /** Settings for smarttable to populate the table with columns @public */
+ public settings: object = {};
+
+ /** operational State created data @public */
+ public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+ /** operational State in creation data @public */
+ public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+ /** operational State in deletion data @public */
+ public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = true;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Class for empty and present data @public */
+ public checkDataClass: string;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** dataService to pass the data from one component to another @private */
+ private dataService: DataService;
+
+ /** Formation of appropriate Data for LocalDatasource @private */
+ private ksuData: {}[] = [];
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ /** Instance of the modal service @private */
+ private modalService: NgbModal;
+
+ /** Instance of subscriptions @private */
+ private generateDataSub: Subscription;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.dataService = this.injector.get(DataService);
+ this.sharedService = this.injector.get(SharedService);
+ this.translateService = this.injector.get(TranslateService);
+ this.modalService = this.injector.get(NgbModal);
+ }
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ }
+
+ /** smart table Header Colums @public */
+ public generateColumns(): void {
+ this.columnList = {
+ name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
+ identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+ filter: {
+ type: 'list',
+ config: {
+ selectText: 'Select',
+ list: [
+ { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+ { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+ ]
+ }
+ },
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
+ } else {
+ return `<span>${row.state}</span>`;
+ }
+ }
+ },
+ created: { title: this.translateService.instant('CREATED'), width: '10%' },
+ modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+ Actions: {
+ name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD => row,
+ renderComponent: K8sActionComponent
+ }
+ };
+ }
+
+ /** smart table Data Settings @public */
+ public generateSettings(): void {
+ this.settings = {
+ columns: this.columnList,
+ actions: { add: false, edit: false, delete: false, position: 'right' },
+ attr: this.sharedService.tableClassConfig(),
+ pager: this.sharedService.paginationPagerConfig(),
+ noDataMessage: this.translateService.instant('NODATAMSG')
+ };
+ }
+
+ /** smart table listing manipulation @public */
+ public onChange(perPageValue: number): void {
+ this.dataSource.setPaging(1, perPageValue, true);
+ }
+
+ /** smart table listing manipulation @public */
+ public onUserRowSelect(event: MessageEvent): void {
+ Object.assign(event.data, { page: 'k8-ksu' });
+ this.dataService.changeMessage(event.data);
+ }
+
+ /** Compose new KSU @public */
+ public addKSU(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(KSUAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'add';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /**
+ * Lifecyle hook which get trigger on component destruction
+ */
+ public ngOnDestroy(): void {
+ this.generateDataSub.unsubscribe();
+ }
+
+ /** Generate KSU object from loop and return for the datasource @public */
+ public generateKSUData(ksudata: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+ return {
+ name: ksudata.name,
+ identifier: ksudata._id,
+ created: this.sharedService.convertEpochTime(Number(ksudata._admin.created)),
+ modified: this.sharedService.convertEpochTime(Number(ksudata._admin.modified)),
+ description: ksudata.description,
+ pageType: 'k8-ksu',
+ state: ksudata.state
+ };
+ }
+
+ /** Fetching the data from server to Load in the smarttable @protected */
+ protected generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.KSU_URL).subscribe((kSUData: K8SCreateCLUSTERDATA[]) => {
+ this.ksuData = [];
+ kSUData.forEach((KSUDetail: INFRACONFIGPAYLOAD) => {
+ const ksuDataObj: INFRACONFIGPAYLOAD = this.generateKSUData(KSUDetail);
+ this.ksuData.push(ksuDataObj);
+ });
+ if (this.ksuData.length > 0) {
+ this.checkDataClass = 'dataTables_present';
+ } else {
+ this.checkDataClass = 'dataTables_empty';
+ }
+ this.dataSource.load(this.ksuData).then((data: boolean) => {
+ this.isLoadingResults = false;
+ }).catch(() => {
+ this.isLoadingResults = false;
+ });
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.html b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.html
new file mode 100644
index 0000000..34fb3fc
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.html
@@ -0,0 +1,45 @@
+<!--
+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="d-flex align-items-center header-style">{{'PAGE.K8S.APP' | translate}}</div>
+ <span class="button">
+ <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Profile' | translate}}" (click)="addProfile()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.CREATEPROFILE' | translate}}
+ </button>
+ </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+ <div class="col-auto me-auto">
+ <nav class="custom-items-config">
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+ </nav>
+ </div>
+ <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+ <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
+ </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.scss b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.ts b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.ts
new file mode 100644
index 0000000..4772c4c
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-app-profile-details/K8sAppProfileComponent.ts
@@ -0,0 +1,254 @@
+/*
+ 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 K8sAppProfileComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { K8sInfraConfigAddComponent } from '../k8s-infra-config-add/K8sInfraConfigAddComponent';
+/**
+ * Creating Component
+ * @Component takes K8sAppProfileComponent.html as template url
+ */
+@Component({
+ selector: 'app-app-profile',
+ templateUrl: './K8sAppProfileComponent.html',
+ styleUrls: ['./K8sAppProfileComponent.scss']
+})
+/** Exporting a class @exports K8sAppProfileComponent */
+export class K8sAppProfileComponent implements OnInit, OnDestroy {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** handle translate @public */
+ public translateService: TranslateService;
+
+ /** Data of smarttable populate through LocalDataSource @public */
+ public dataSource: LocalDataSource = new LocalDataSource();
+
+ /** Columns list of the smart table @public */
+ public columnList: object = {};
+
+ /** Settings for smarttable to populate the table with columns @public */
+ public settings: object = {};
+
+ /** operational State created data @public */
+ public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+ /** operational State in creation data @public */
+ public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+ /** operational State in deletion data @public */
+ public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = true;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Class for empty and present data @public */
+ public checkDataClass: string;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** dataService to pass the data from one component to another @private */
+ private dataService: DataService;
+
+ /** Formation of appropriate Data for LocalDatasource @private */
+ private profileData: {}[] = [];
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ /** Instance of the modal service @private */
+ private modalService: NgbModal;
+
+ /** Instance of subscriptions @private */
+ private generateDataSub: Subscription;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.dataService = this.injector.get(DataService);
+ this.sharedService = this.injector.get(SharedService);
+ this.translateService = this.injector.get(TranslateService);
+ this.modalService = this.injector.get(NgbModal);
+ }
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ }
+
+ /** smart table Header Colums @public */
+ public generateColumns(): void {
+ this.columnList = {
+ name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
+ identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+ filter: {
+ type: 'list',
+ config: {
+ selectText: 'Select',
+ list: [
+ { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+ { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+ ]
+ }
+ },
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
+ } else {
+ return `<span>${row.state}</span>`;
+ }
+ }
+ },
+ created: { title: this.translateService.instant('CREATED'), width: '10%' },
+ modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+ Actions: {
+ name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD => row,
+ renderComponent: K8sActionComponent
+ }
+ };
+ }
+
+ /** smart table Data Settings @public */
+ public generateSettings(): void {
+ this.settings = {
+ columns: this.columnList,
+ actions: { add: false, edit: false, delete: false, position: 'right' },
+ attr: this.sharedService.tableClassConfig(),
+ pager: this.sharedService.paginationPagerConfig(),
+ noDataMessage: this.translateService.instant('NODATAMSG')
+ };
+ }
+
+ /** smart table listing manipulation @public */
+ public onChange(perPageValue: number): void {
+ this.dataSource.setPaging(1, perPageValue, true);
+ }
+
+ /** smart table listing manipulation @public */
+ public onUserRowSelect(event: MessageEvent): void {
+ Object.assign(event.data, { page: 'k8-app-profile' });
+ this.dataService.changeMessage(event.data);
+ }
+
+ /** Compose new profile @public */
+ public addProfile(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sInfraConfigAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'app-profile';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /**
+ * Lifecyle hook which get trigger on component destruction
+ */
+ public ngOnDestroy(): void {
+ this.generateDataSub.unsubscribe();
+ }
+
+ /** Generate profile object from loop and return for the datasource @public */
+ public generateprofileData(profileData: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+ return {
+ name: profileData.name,
+ identifier: profileData._id,
+ created: this.sharedService.convertEpochTime(Number(profileData._admin.created)),
+ modified: this.sharedService.convertEpochTime(Number(profileData._admin.modified)),
+ description: profileData.description,
+ pageType: 'app-profile',
+ state: profileData.state
+ };
+ }
+
+ /** Fetching the data from server to Load in the smarttable @protected */
+ protected generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SAPPPROFILE_URL).subscribe((profileDatas: K8SCreateCLUSTERDATA[]) => {
+ this.profileData = [];
+ profileDatas.forEach((profileData: INFRACONFIGPAYLOAD) => {
+ const profileDataObj: INFRACONFIGPAYLOAD = this.generateprofileData(profileData);
+ this.profileData.push(profileDataObj);
+ });
+ if (this.profileData.length > 0) {
+ this.checkDataClass = 'dataTables_present';
+ } else {
+ this.checkDataClass = 'dataTables_empty';
+ }
+ this.dataSource.load(this.profileData).then((data: boolean) => {
+ this.isLoadingResults = false;
+ }).catch(() => {
+ this.isLoadingResults = false;
+ });
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.html b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.html
new file mode 100644
index 0000000..493cb5b
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.html
@@ -0,0 +1,52 @@
+<!--
+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)
+-->
+<form [formGroup]="profileForm" (ngSubmit)="profileSubmit();">
+ <div class="modal-header">
+ <h4 *ngIf="isAdd" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.CREATEPROFILE' | translate}}</h4>
+ <h4 *ngIf="isEdit" class="modal-title" id="modal-basic-title">{{'PAGE.K8S.EDITPROFILE' | translate}}</h4>
+ <button class="button-xs" type="button" class="close" aria-label="Close" (click)="activeModal.close()">
+ <i class="fas fa-times-circle text-danger"></i>
+ </button>
+ </div>
+ <div class="modal-body modal-body-custom-height">
+ <div class="form-group row mb-3">
+ <label class="col-sm-12 col-form-label mandatory-label"
+ [ngClass]="{'text-danger': profileForm.invalid === true && submitted === true}">{{'MANDATORYCHECK' |
+ translate}}</label>
+ <label class="col-sm-4 col-form-label" for="name">{{'PAGE.K8S.NAME' | translate}}*</label>
+ <div class="col-sm-8">
+ <input autocomplete="off" class="form-control" placeholder="{{'PAGE.K8S.NAME' | translate}}" type="text"
+ formControlName="name" id="name" [ngClass]="{ 'is-invalid': submitted && f.name.errors }" required>
+ </div>
+ </div>
+ <div class="form-group row mb-3">
+ <label class="col-sm-4 col-form-label" for="description">{{'PAGE.K8S.DESCRIPTION' | translate}}*</label>
+ <div class="col-sm-8">
+ <textarea class="form-control" placeholder="{{'PAGE.K8S.DESCRIPTION' | translate}}" type="text"
+ formControlName="description" id="description"
+ [ngClass]="{ 'is-invalid': submitted && f.description.errors }" required></textarea>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-danger" (click)="activeModal.close()">{{'CANCEL' | translate}}</button>
+ <button *ngIf="isAdd" type="submit" class="btn btn-primary">{{'CREATE' | translate}}</button>
+ <button *ngIf="isEdit" type="submit" class="btn btn-primary">{{'EDIT' | translate}}</button>
+ </div>
+</form>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.scss b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.ts b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.ts
new file mode 100644
index 0000000..5299323
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-add/K8sInfraConfigAddComponent.ts
@@ -0,0 +1,220 @@
+/*
+ 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 K8sInfraConfigAddComponent.ts.
+ */
+import { HttpHeaders } from '@angular/common/http';
+import { Component,Injector, Input, OnInit} from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { NotifierService } from 'angular-notifier';
+import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA, TYPESECTION, URLPARAMS } from 'CommonModel';
+import { environment } from 'environment';
+import { INFRACONFIGPAYLOAD} from 'K8sModel';
+import { RestService } from 'RestService';
+import { SharedService, isNullOrUndefined } from 'SharedService';
+/**
+ * Creating Component
+ * @Component takes K8sInfraConfigAddComponent.html as template url
+ */
+@Component({
+ selector: 'app-infra-config',
+ templateUrl: './K8sInfraConfigAddComponent.html',
+ styleUrls: ['./K8sInfraConfigAddComponent.scss']
+})
+/** Exporting a class @exports K8sInfraConfigAddComponent */
+export class K8sInfraConfigAddComponent implements OnInit {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** FormGroup instance added to the form @ html @public */
+ public profileForm: FormGroup;
+
+ /** Instance for active modal service @public */
+ public activeModal: NgbActiveModal;
+
+ /** Form submission Add */
+ public submitted: boolean = false;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = false;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** profile url @public */
+ public profileUrl: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileType: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileID: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileName: string;
+
+ /** Input contains Modal dialog component Instance @public */
+ @Input() public profileDescription: string;
+
+ /** check Add @public */
+ public isAdd = false;
+
+ /** check Edit @public */
+ public isEdit = false;
+
+ /** FormBuilder instance added to the formBuilder @private */
+ private formBuilder: FormBuilder;
+
+ /** Utilizes rest service for any CRUD operations @private */
+ private restService: RestService;
+
+ /** Notifier service to popup notification @private */
+ private notifierService: NotifierService;
+
+ /** Contains tranlsate instance @private */
+ private translateService: TranslateService;
+
+ /** Controls the header form @private */
+ private headers: HttpHeaders;
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.activeModal = this.injector.get(NgbActiveModal);
+ this.formBuilder = this.injector.get(FormBuilder);
+ this.notifierService = this.injector.get(NotifierService);
+ this.translateService = this.injector.get(TranslateService);
+ this.sharedService = this.injector.get(SharedService);
+ }
+
+ public ngOnInit(): void {
+ /** On Initializing call the methods */
+ this.profileFormAction();
+ this.headers = new HttpHeaders({
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
+ });
+ if (!isNullOrUndefined(this.profileID)) {
+ this.isEdit = true;
+ this.profileForm.patchValue({ name: this.profileName, description: this.profileDescription });
+ } else {
+ this.isAdd = true;
+ }
+ }
+
+ /** On modal initializing forms @public */
+ public profileFormAction(): void {
+ this.profileForm = this.formBuilder.group({
+ name: ['', [Validators.required]],
+ default: [null],
+ description: ['', [Validators.required]]
+ });
+ }
+
+ /** convenience getter for easy access to form fields */
+ get f(): FormGroup['controls'] { return this.profileForm.controls; }
+
+ /** On modal submit profileSubmit will called @public */
+ public profileSubmit(): void {
+ this.submitted = true;
+ this.sharedService.cleanForm(this.profileForm);
+ if (this.profileForm.invalid) {
+ return;
+ }
+ if (!isNullOrUndefined(this.profileID)) {
+ this.editProfile(this.profileType);
+ } else {
+ this.addProfile();
+ }
+ }
+ /** Add profile @public */
+ public addProfile(): void {
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ if (this.profileType === 'infra-config') {
+ this.profileUrl = environment.K8SINFRACONFIGPROFILE_URL;
+ } else if (this.profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SINFRACONTROLLERPROFILE_URL;
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SAPPPROFILE_URL;
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SRESOURCEPROFILE_URL;
+ }
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl,
+ httpOptions: { headers: this.headers }
+ };
+
+ this.isLoadingResults = true;
+ const payload: INFRACONFIGPAYLOAD = {
+ name: this.profileForm.value.name,
+ description: this.profileForm.value.description
+ };
+ this.restService.postResource(apiURLHeader, payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.PROFILECREATEDSUCCESSFULLY'));
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ this.isLoadingResults = false;
+ });
+ }
+
+ /** Edit profile @public */
+ public editProfile(profileType: string): void {
+ const modalData: MODALCLOSERESPONSEDATA = {
+ message: 'Done'
+ };
+ this.isLoadingResults = true;
+ if (profileType === 'infra-config') {
+ this.profileUrl = environment.K8SINFRACONFIGPROFILE_URL + '/' + this.profileID;
+ } else if (profileType === 'infra-controller') {
+ this.profileUrl = environment.K8SINFRACONTROLLERPROFILE_URL + '/' + this.profileID;
+ } else if (this.profileType === 'app-profile') {
+ this.profileUrl = environment.K8SAPPPROFILE_URL + '/' + this.profileID;
+ } else if (this.profileType === 'resource-profile') {
+ this.profileUrl = environment.K8SRESOURCEPROFILE_URL + '/' + this.profileID;
+ }
+ const apiURLHeader: APIURLHEADER = {
+ url: this.profileUrl,
+ httpOptions: { headers: this.headers }
+ };
+ const payload: INFRACONFIGPAYLOAD = {
+ name: this.profileForm.value.name,
+ description: this.profileForm.value.description
+ };
+
+ this.restService.patchResource(apiURLHeader, payload).subscribe((result: {}) => {
+ this.activeModal.close(modalData);
+ this.isLoadingResults = false;
+ this.notifierService.notify('success',
+ this.translateService.instant('PAGE.K8S.PROFILEEDITEDSUCCESSFULLY'));
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'post');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.html b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.html
new file mode 100644
index 0000000..81761d5
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.html
@@ -0,0 +1,45 @@
+<!--
+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="d-flex align-items-center header-style">{{'PAGE.K8S.INFRACONFIG' | translate}}</div>
+ <span class="button">
+ <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Profile' | translate}}" (click)="addProfile()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.CREATEPROFILE' | translate}}
+ </button>
+ </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+ <div class="col-auto me-auto">
+ <nav class="custom-items-config">
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+ </nav>
+ </div>
+ <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+ <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
+ </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.scss b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.ts b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.ts
new file mode 100644
index 0000000..760124b
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-config-details/K8sInfraConfigProfileComponent.ts
@@ -0,0 +1,254 @@
+/*
+ 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 K8sInfraConfigProfileComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA, K8SCREATEDATADISPLAY } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { K8sInfraConfigAddComponent } from '../k8s-infra-config-add/K8sInfraConfigAddComponent';
+/**
+ * Creating Component
+ * @Component takes K8sInfraConfigProfileComponent.html as template url
+ */
+@Component({
+ selector: 'app-infra-config-profile',
+ templateUrl: './K8sInfraConfigProfileComponent.html',
+ styleUrls: ['./K8sInfraConfigProfileComponent.scss']
+})
+/** Exporting a class @exports K8sInfraConfigProfileComponent */
+export class K8sInfraConfigProfileComponent implements OnInit, OnDestroy {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** handle translate @public */
+ public translateService: TranslateService;
+
+ /** Data of smarttable populate through LocalDataSource @public */
+ public dataSource: LocalDataSource = new LocalDataSource();
+
+ /** Columns list of the smart table @public */
+ public columnList: object = {};
+
+ /** Settings for smarttable to populate the table with columns @public */
+ public settings: object = {};
+
+ /** operational State created data @public */
+ public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+ /** operational State in creation data @public */
+ public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+ /** operational State in deletion data @public */
+ public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = true;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Class for empty and present data @public */
+ public checkDataClass: string;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** dataService to pass the data from one component to another @private */
+ private dataService: DataService;
+
+ /** Formation of appropriate Data for LocalDatasource @private */
+ private profileData: {}[] = [];
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ /** Instance of the modal service @private */
+ private modalService: NgbModal;
+
+ /** Instance of subscriptions @private */
+ private generateDataSub: Subscription;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.dataService = this.injector.get(DataService);
+ this.sharedService = this.injector.get(SharedService);
+ this.translateService = this.injector.get(TranslateService);
+ this.modalService = this.injector.get(NgbModal);
+ }
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ }
+
+ /** smart table Header Colums @public */
+ public generateColumns(): void {
+ this.columnList = {
+ name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
+ identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+ filter: {
+ type: 'list',
+ config: {
+ selectText: 'Select',
+ list: [
+ { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+ { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+ ]
+ }
+ },
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
+ } else {
+ return `<span>${row.state}</span>`;
+ }
+ }
+ },
+ created: { title: this.translateService.instant('CREATED'), width: '10%' },
+ modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+ Actions: {
+ name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD => row,
+ renderComponent: K8sActionComponent
+ }
+ };
+ }
+
+ /** smart table Data Settings @public */
+ public generateSettings(): void {
+ this.settings = {
+ columns: this.columnList,
+ actions: { add: false, edit: false, delete: false, position: 'right' },
+ attr: this.sharedService.tableClassConfig(),
+ pager: this.sharedService.paginationPagerConfig(),
+ noDataMessage: this.translateService.instant('NODATAMSG')
+ };
+ }
+
+ /** smart table listing manipulation @public */
+ public onChange(perPageValue: number): void {
+ this.dataSource.setPaging(1, perPageValue, true);
+ }
+
+ /** smart table listing manipulation @public */
+ public onUserRowSelect(event: MessageEvent): void {
+ Object.assign(event.data, { page: 'k8-infra-profile' });
+ this.dataService.changeMessage(event.data);
+ }
+
+ /** Compose new profile @public */
+ public addProfile(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sInfraConfigAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'infra-config';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /**
+ * Lifecyle hook which get trigger on component destruction
+ */
+ public ngOnDestroy(): void {
+ this.generateDataSub.unsubscribe();
+ }
+
+ /** Generate profile object from loop and return for the datasource @public */
+ public generateprofileData(profileData: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+ return {
+ name: profileData.name,
+ identifier: profileData._id,
+ created: this.sharedService.convertEpochTime(Number(profileData._admin.created)),
+ modified: this.sharedService.convertEpochTime(Number(profileData._admin.modified)),
+ description: profileData.description,
+ pageType: 'infra-config',
+ state: profileData.state
+ };
+ }
+
+ /** Fetching the data from server to Load in the smarttable @protected */
+ protected generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SINFRACONFIGPROFILE_URL).subscribe((profileDatas: K8SCreateCLUSTERDATA[]) => {
+ this.profileData = [];
+ profileDatas.forEach((profileData: INFRACONFIGPAYLOAD) => {
+ const profileDataObj: INFRACONFIGPAYLOAD = this.generateprofileData(profileData);
+ this.profileData.push(profileDataObj);
+ });
+ if (this.profileData.length > 0) {
+ this.checkDataClass = 'dataTables_present';
+ } else {
+ this.checkDataClass = 'dataTables_empty';
+ }
+ this.dataSource.load(this.profileData).then((data: boolean) => {
+ this.isLoadingResults = false;
+ }).catch(() => {
+ this.isLoadingResults = false;
+ });
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.html b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.html
new file mode 100644
index 0000000..592a0cb
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.html
@@ -0,0 +1,45 @@
+<!--
+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="d-flex align-items-center header-style">{{'PAGE.K8S.INFRACONTROLLER' | translate}}</div>
+ <span class="button">
+ <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Profile' | translate}}" (click)="addProfile()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.CREATEPROFILE' | translate}}
+ </button>
+ </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+ <div class="col-auto me-auto">
+ <nav class="custom-items-config">
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+ </nav>
+ </div>
+ <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+ <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
+ </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.scss b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.ts b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.ts
new file mode 100644
index 0000000..0402acf
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-infra-controller-details/K8sInfraControllerProfileComponent.ts
@@ -0,0 +1,253 @@
+/*
+ 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 K8sInfraConfigProfileComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA, K8SCREATEDATADISPLAY } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { K8sInfraConfigAddComponent } from '../k8s-infra-config-add/K8sInfraConfigAddComponent';
+/**
+ * Creating Component
+ * @Component takes K8sInfraControllerProfileComponent.html as template url
+ */
+@Component({
+ selector: 'app-infra-controller-profile',
+ templateUrl: './K8sInfraControllerProfileComponent.html',
+ styleUrls: ['./K8sInfraControllerProfileComponent.scss']
+})
+/** Exporting a class @exports K8sInfraControllerProfileComponent */
+export class K8sInfraControllerProfileComponent implements OnInit, OnDestroy {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** handle translate @public */
+ public translateService: TranslateService;
+
+ /** Data of smarttable populate through LocalDataSource @public */
+ public dataSource: LocalDataSource = new LocalDataSource();
+
+ /** Columns list of the smart table @public */
+ public columnList: object = {};
+
+ /** Settings for smarttable to populate the table with columns @public */
+ public settings: object = {};
+
+ /** operational State created data @public */
+ public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+ /** operational State in creation data @public */
+ public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+ /** operational State in deletion data @public */
+ public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = true;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Class for empty and present data @public */
+ public checkDataClass: string;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** dataService to pass the data from one component to another @private */
+ private dataService: DataService;
+
+ /** Formation of appropriate Data for LocalDatasource @private */
+ private profileData: {}[] = [];
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ /** Instance of the modal service @private */
+ private modalService: NgbModal;
+
+ /** Instance of subscriptions @private */
+ private generateDataSub: Subscription;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.dataService = this.injector.get(DataService);
+ this.sharedService = this.injector.get(SharedService);
+ this.translateService = this.injector.get(TranslateService);
+ this.modalService = this.injector.get(NgbModal);
+ }
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ }
+
+ /** smart table Header Colums @public */
+ public generateColumns(): void {
+ this.columnList = {
+ name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
+ identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+ filter: {
+ type: 'list',
+ config: {
+ selectText: 'Select',
+ list: [
+ { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+ { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+ ]
+ }
+ },
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
+ } else {
+ return `<span>${row.state}</span>`;
+ }
+ }
+ },
+ created: { title: this.translateService.instant('CREATED'), width: '10%' },
+ modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+ Actions: {
+ name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+ valuePrepareFunction: (cell: K8SCREATEDATADISPLAY, row: K8SCREATEDATADISPLAY): K8SCREATEDATADISPLAY => row,
+ renderComponent: K8sActionComponent
+ }
+ };
+ }
+
+ /** smart table Data Settings @public */
+ public generateSettings(): void {
+ this.settings = {
+ columns: this.columnList,
+ actions: { add: false, edit: false, delete: false, position: 'right' },
+ attr: this.sharedService.tableClassConfig(),
+ pager: this.sharedService.paginationPagerConfig(),
+ noDataMessage: this.translateService.instant('NODATAMSG')
+ };
+ }
+
+ /** smart table listing manipulation @public */
+ public onChange(perPageValue: number): void {
+ this.dataSource.setPaging(1, perPageValue, true);
+ }
+
+ /** smart table listing manipulation @public */
+ public onUserRowSelect(event: MessageEvent): void {
+ Object.assign(event.data, { page: 'k8-infra-controller' });
+ this.dataService.changeMessage(event.data);
+ }
+
+ /** Compose new Profile @public */
+ public addProfile(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sInfraConfigAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'infra-controller';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /**
+ * Lifecyle hook which get trigger on component destruction
+ */
+ public ngOnDestroy(): void {
+ this.generateDataSub.unsubscribe();
+ }
+ /** Generate profile object from loop and return for the datasource @public */
+ public generateprofileData(profileData: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+ return {
+ name: profileData.name,
+ identifier: profileData._id,
+ created: this.sharedService.convertEpochTime(Number(profileData._admin.created)),
+ modified: this.sharedService.convertEpochTime(Number(profileData._admin.modified)),
+ description: profileData.description,
+ pageType: 'infra-controller',
+ state: profileData.state
+ };
+ }
+
+ /** Fetching the data from server to Load in the smarttable @protected */
+ protected generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SINFRACONTROLLERPROFILE_URL).subscribe((profileDatas: K8SCreateCLUSTERDATA[]) => {
+ this.profileData = [];
+ profileDatas.forEach((profileData: INFRACONFIGPAYLOAD) => {
+ const profileDataObj: INFRACONFIGPAYLOAD = this.generateprofileData(profileData);
+ this.profileData.push(profileDataObj);
+ });
+ if (this.profileData.length > 0) {
+ this.checkDataClass = 'dataTables_present';
+ } else {
+ this.checkDataClass = 'dataTables_empty';
+ }
+ this.dataSource.load(this.profileData).then((data: boolean) => {
+ this.isLoadingResults = false;
+ }).catch(() => {
+ this.isLoadingResults = false;
+ });
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.html b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.html
new file mode 100644
index 0000000..2e76c13
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.html
@@ -0,0 +1,45 @@
+<!--
+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="d-flex align-items-center header-style">{{'PAGE.K8S.RESOURCE' | translate}}</div>
+ <span class="button">
+ <button class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Profile' | translate}}" (click)="addProfile()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.CREATEPROFILE' | translate}}
+ </button>
+ </span>
+</div>
+<div class="mt-2 mb-2 list-utilites-actions">
+ <div class="col-auto me-auto">
+ <nav class="custom-items-config">
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
+ </nav>
+ </div>
+ <page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
+ <page-reload></page-reload>
+</div>
+<div class="smarttable-style bg-white mt-1">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
+ </ng2-smart-table>
+</div>
+<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.scss b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.scss
new file mode 100644
index 0000000..c55461a
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.scss
@@ -0,0 +1,17 @@
+/*
+ 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)
+*/
\ No newline at end of file
diff --git a/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.ts b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.ts
new file mode 100644
index 0000000..296b0f6
--- /dev/null
+++ b/src/app/k8s/k8s-profile/k8s-resource-profile/K8sResourceProfileComponent.ts
@@ -0,0 +1,254 @@
+/*
+ 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 K8sInfraConfigProfileComponent.ts.
+ */
+import { Component, Injector, OnDestroy, OnInit } from '@angular/core';
+import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateService } from '@ngx-translate/core';
+import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
+import { DataService } from 'DataService';
+import { environment } from 'environment';
+import { K8sActionComponent } from 'K8sActionComponent';
+import { INFRACONFIGPAYLOAD, K8SCreateCLUSTERDATA, K8SCREATEDATADISPLAY } from 'K8sModel';
+import { LocalDataSource } from 'ng2-smart-table';
+import { RestService } from 'RestService';
+import { Subscription } from 'rxjs';
+import { SharedService } from 'SharedService';
+import { K8sInfraConfigAddComponent } from '../k8s-infra-config-add/K8sInfraConfigAddComponent';
+/**
+ * Creating Component
+ * @Component takes K8sInfraConfigProfileComponent.html as template url
+ */
+@Component({
+ selector: 'app-resource-profile',
+ templateUrl: './K8sResourceProfileComponent.html',
+ styleUrls: ['./K8sResourceProfileComponent.scss']
+})
+/** Exporting a class @exports K8sResourceProfileComponent */
+export class K8sResourceProfileComponent implements OnInit, OnDestroy {
+ /** To inject services @public */
+ public injector: Injector;
+
+ /** handle translate @public */
+ public translateService: TranslateService;
+
+ /** Data of smarttable populate through LocalDataSource @public */
+ public dataSource: LocalDataSource = new LocalDataSource();
+
+ /** Columns list of the smart table @public */
+ public columnList: object = {};
+
+ /** Settings for smarttable to populate the table with columns @public */
+ public settings: object = {};
+
+ /** operational State created data @public */
+ public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
+
+ /** operational State in creation data @public */
+ public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
+
+ /** operational State in deletion data @public */
+ public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** Check the loading results @public */
+ public isLoadingResults: boolean = true;
+
+ /** Give the message for the loading @public */
+ public message: string = 'PLEASEWAIT';
+
+ /** Class for empty and present data @public */
+ public checkDataClass: string;
+
+ /** Instance of the rest service @private */
+ private restService: RestService;
+
+ /** dataService to pass the data from one component to another @private */
+ private dataService: DataService;
+
+ /** Formation of appropriate Data for LocalDatasource @private */
+ private profileData: {}[] = [];
+
+ /** Contains all methods related to shared @private */
+ private sharedService: SharedService;
+
+ /** Instance of the modal service @private */
+ private modalService: NgbModal;
+
+ /** Instance of subscriptions @private */
+ private generateDataSub: Subscription;
+
+ constructor(injector: Injector) {
+ this.injector = injector;
+ this.restService = this.injector.get(RestService);
+ this.dataService = this.injector.get(DataService);
+ this.sharedService = this.injector.get(SharedService);
+ this.translateService = this.injector.get(TranslateService);
+ this.modalService = this.injector.get(NgbModal);
+ }
+ /** Lifecyle Hooks the trigger before component is instantiate @public */
+ public ngOnInit(): void {
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ }
+
+ /** smart table Header Colums @public */
+ public generateColumns(): void {
+ this.columnList = {
+ name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
+ identifier: { title: this.translateService.instant('IDENTIFIER'), width: '15%' },
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
+ filter: {
+ type: 'list',
+ config: {
+ selectText: 'Select',
+ list: [
+ { value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
+ { value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
+ ]
+ }
+ },
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): string => {
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
+ } else {
+ return `<span>${row.state}</span>`;
+ }
+ }
+ },
+ created: { title: this.translateService.instant('CREATED'), width: '10%' },
+ modified: { title: this.translateService.instant('MODIFIED'), width: '10%' },
+ Actions: {
+ name: 'Action', width: '5%', filter: false, sort: false, title: this.translateService.instant('ACTIONS'), type: 'custom',
+ valuePrepareFunction: (cell: INFRACONFIGPAYLOAD, row: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD => row,
+ renderComponent: K8sActionComponent
+ }
+ };
+ }
+
+ /** smart table Data Settings @public */
+ public generateSettings(): void {
+ this.settings = {
+ columns: this.columnList,
+ actions: { add: false, edit: false, delete: false, position: 'right' },
+ attr: this.sharedService.tableClassConfig(),
+ pager: this.sharedService.paginationPagerConfig(),
+ noDataMessage: this.translateService.instant('NODATAMSG')
+ };
+ }
+
+ /** smart table listing manipulation @public */
+ public onChange(perPageValue: number): void {
+ this.dataSource.setPaging(1, perPageValue, true);
+ }
+
+ /** smart table listing manipulation @public */
+ public onUserRowSelect(event: MessageEvent): void {
+ Object.assign(event.data, { page: 'k8-resource-profile' });
+ this.dataService.changeMessage(event.data);
+ }
+
+ /** Compose new Profile @public */
+ public addProfile(): void {
+ // eslint-disable-next-line security/detect-non-literal-fs-filename
+ const modalRef: NgbModalRef = this.modalService.open(K8sInfraConfigAddComponent, { backdrop: 'static' });
+ modalRef.componentInstance.profileType = 'resource-profile';
+ modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+ if (result) {
+ this.sharedService.callData();
+ }
+ }).catch((): void => {
+ // Catch Navigation Error
+ });
+ }
+
+ /**
+ * Lifecyle hook which get trigger on component destruction
+ */
+ public ngOnDestroy(): void {
+ this.generateDataSub.unsubscribe();
+ }
+
+ /** Generate profile object from loop and return for the datasource @public */
+ public generateProfileData(profileData: INFRACONFIGPAYLOAD): INFRACONFIGPAYLOAD {
+ return {
+ name: profileData.name,
+ identifier: profileData._id,
+ created: this.sharedService.convertEpochTime(Number(profileData._admin.created)),
+ modified: this.sharedService.convertEpochTime(Number(profileData._admin.modified)),
+ description: profileData.description,
+ pageType: 'resource-profile',
+ state: profileData.state
+ };
+ }
+
+ /** Fetching the data from server to Load in the smarttable @protected */
+ protected generateData(): void {
+ this.isLoadingResults = true;
+ this.restService.getResource(environment.K8SRESOURCEPROFILE_URL).subscribe((profileDatas: K8SCreateCLUSTERDATA[]) => {
+ this.profileData = [];
+ profileDatas.forEach((profileData: INFRACONFIGPAYLOAD) => {
+ const profileDataObj: INFRACONFIGPAYLOAD = this.generateProfileData(profileData);
+ this.profileData.push(profileDataObj);
+ });
+ if (this.profileData.length > 0) {
+ this.checkDataClass = 'dataTables_present';
+ } else {
+ this.checkDataClass = 'dataTables_empty';
+ }
+ this.dataSource.load(this.profileData).then((data: boolean) => {
+ this.isLoadingResults = false;
+ }).catch(() => {
+ this.isLoadingResults = false;
+ });
+ }, (error: ERRORDATA) => {
+ this.restService.handleError(error, 'get');
+ this.isLoadingResults = false;
+ });
+ }
+}
diff --git a/src/app/k8s/k8scluster/K8sClusterComponent.html b/src/app/k8s/k8scluster/K8sClusterComponent.html
index 613e6aa..0bb251e 100644
--- a/src/app/k8s/k8scluster/K8sClusterComponent.html
+++ b/src/app/k8s/k8scluster/K8sClusterComponent.html
@@ -16,27 +16,49 @@
Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
-->
<div class="d-flex flex-row justify-content-between">
- <div class="d-flex align-items-center header-style">{{'PAGE.K8S.REGISTERK8CLUSTER' | translate}}</div>
- <span class="button">
- <button class="btn btn-primary" type="button" placement="top" container="body" ngbTooltip="{{'PAGE.K8S.ADDK8CLUSTER' | translate}}"
- (click)="addK8sCluster()">
- <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.ADDK8CLUSTER' | translate}}
+ <div class="d-flex align-items-center header-style">
+ <div class="switches-container justify-content-start">
+ <input type="radio" id="switchRegister" name="switchPlan" (change)="onChangeEvent($event.target.value)"
+ value="Registered" checked="checked" />
+ <input type="radio" id="switchManage" name="switchPlan" (change)="onChangeEvent($event.target.value)"
+ value="Managed" />
+ <label for="switchRegister">{{'PAGE.K8S.REGISTERED' | translate}}</label>
+ <label for="switchManage">{{'PAGE.K8S.MANAGED' | translate}}</label>
+ <div class="switch-wrapper">
+ <div class="switch">
+ <div>{{'PAGE.K8S.REGISTERED' | translate}}</div>
+ <div>{{'PAGE.K8S.MANAGED' | translate}}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <span class="button justify-content-end">
+ <button *ngIf="isCluster === 'Registered'" class="btn btn-primary me-2" type="button" placement="top"
+ container="body" ngbTooltip="{{'PAGE.K8S.REGISTERCLUSTER' | translate}}" (click)="addK8sCluster()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.REGISTERCLUSTER' | translate}}
+ </button>
+ <button *ngIf="isCluster === 'Managed'" class="btn btn-primary me-2" type="button" placement="top" container="body"
+ ngbTooltip="{{'Create Cluster' | translate}}" (click)="addK8sCluster()">
+ <i class="fas fa-plus-circle" aria-hidden="true"></i> {{'PAGE.K8S.CREATECLUSTER' | translate}}
</button>
</span>
</div>
<div class="mt-2 mb-2 list-utilites-actions">
<div class="col-auto me-auto">
<nav class="custom-items-config">
- <span><i class="fas fa-clock text-warning"></i>{{operationalStateFirstStep}}</span>
- <span><i class="fas fa-check-circle text-success"></i>{{operationalStateSecondStep}}</span>
- <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-clock text-success"></i>{{operationalStateFirstStep}}</span>
+ <span><i class="fas fa-spinner text-warning"></i>{{operationalStateSecondStep}}</span>
+ <span><i class="fas fa-spinner text-danger"></i>{{operationalStateThirdStep}}</span>
+ <span><i class="fas fa-times-circle text-danger"></i>{{operationalStateFourthStep}}</span>
+ <span><i class="fas fa-times-circle text-warning"></i>{{operationalStateFifthStep}}</span>
</nav>
</div>
<page-per-row class="me-2" (pagePerRow)="onChange($event)"></page-per-row>
<page-reload></page-reload>
</div>
<div class="smarttable-style bg-white mt-1">
- <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource" (userRowSelect)="onUserRowSelect($event)">
+ <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+ (userRowSelect)="onUserRowSelect($event)">
</ng2-smart-table>
</div>
<app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
diff --git a/src/app/k8s/k8scluster/K8sClusterComponent.scss b/src/app/k8s/k8scluster/K8sClusterComponent.scss
index 021d205..d194553 100644
--- a/src/app/k8s/k8scluster/K8sClusterComponent.scss
+++ b/src/app/k8s/k8scluster/K8sClusterComponent.scss
@@ -14,4 +14,89 @@
limitations under the License.
Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
-*/
\ No newline at end of file
+*/
+.switches-container {
+ border-bottom: 1px solid #5f5f5f;
+ background-color: #054c8c;
+ border-radius: 2px;
+ width: 230px;
+ position: relative;
+ display: block;
+ padding: 0;
+ line-height: 2em;
+ border-radius: 3rem;
+ margin-left: auto;
+ margin-right: auto;
+ height: 36px;
+}
+
+.switches-container input {
+ visibility: hidden;
+ position: absolute;
+ top: 0;
+}
+
+.switches-container label {
+ width: 50%;
+ padding: 0;
+ margin: 0;
+ text-align: center;
+ cursor: pointer;
+ color: white;
+ font-size: 0.875rem;
+ font-weight: 400;
+}
+
+.switch-wrapper {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 50%;
+ padding: 0.15rem;
+ z-index: 3;
+ transition: transform 0.5s cubic-bezier(0.77, 0, 0.175, 1);
+}
+
+.switch {
+ border-radius: 3rem;
+ background: white;
+ height: 100%;
+ width: 110px;
+ margin-top: 1px;
+ margin-right: 1px;
+}
+
+.switch div {
+ width: 100%;
+ text-align: center;
+ opacity: 0;
+ display: block;
+ color: #054c8c;
+ font-size: 0.875rem;
+ font-weight: 400;
+ transition: opacity 0.2s cubic-bezier(0.77, 0, 0.175, 1) 0.125s;
+ will-change: opacity;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+/* slide the switch box from right to left */
+.switches-container input:nth-of-type(1):checked ~ .switch-wrapper {
+ transform: translateX(0%);
+}
+
+/* slide the switch box from left to right */
+.switches-container input:nth-of-type(2):checked ~ .switch-wrapper {
+ transform: translateX(100%);
+}
+
+/* toggle the switch box labels - first checkbox:checked - show first switch div */
+.switches-container input:nth-of-type(1):checked ~ .switch-wrapper .switch div:nth-of-type(1) {
+ opacity: 1;
+}
+
+/* toggle the switch box labels - second checkbox:checked - show second switch div */
+.switches-container input:nth-of-type(2):checked ~ .switch-wrapper .switch div:nth-of-type(2) {
+ opacity: 1;
+}
diff --git a/src/app/k8s/k8scluster/K8sClusterComponent.ts b/src/app/k8s/k8scluster/K8sClusterComponent.ts
index 88a4fb6..ee98ed5 100644
--- a/src/app/k8s/k8scluster/K8sClusterComponent.ts
+++ b/src/app/k8s/k8scluster/K8sClusterComponent.ts
@@ -26,7 +26,7 @@
import { environment } from 'environment';
import { K8sActionComponent } from 'K8sActionComponent';
import { K8sAddClusterComponent } from 'K8sAddClusterComponent';
-import { K8SCLUSTERDATA, K8SCLUSTERDATADISPLAY } from 'K8sModel';
+import { K8SCLUSTERDATA, K8SCLUSTERDATADISPLAY, K8SCREATEDATADISPLAY } from 'K8sModel';
import { LocalDataSource } from 'ng2-smart-table';
import { RestService } from 'RestService';
import { Subscription } from 'rxjs';
@@ -66,15 +66,27 @@
/** Class for empty and present data @public */
public checkDataClass: string;
- /** operational State init data @public */
+ /** operational State created data @public */
public operationalStateFirstStep: string = CONFIGCONSTANT.k8OperationalStateFirstStep;
- /** operational State running data @public */
+ /** operational State in creation data @public */
public operationalStateSecondStep: string = CONFIGCONSTANT.k8OperationalStateStateSecondStep;
- /** operational State failed data @public */
+ /** operational State in deletion data @public */
public operationalStateThirdStep: string = CONFIGCONSTANT.k8OperationalStateThirdStep;
+ /** operational State failed deletion data @public */
+ public operationalStateFourthStep: string = CONFIGCONSTANT.k8OperationalStateFourthStep;
+
+ /** operational State failed creation data @public */
+ public operationalStateFifthStep: string = CONFIGCONSTANT.k8OperationalStateFifthStep;
+
+ /** cluster Type @public */
+ public isCluster: string = 'Registered';
+
+ /** cluster @public */
+ public clusterUrl: string;
+
/** Instance of the rest service @private */
private restService: RestService;
@@ -107,6 +119,7 @@
this.generateSettings();
this.generateData();
this.generateDataSub = this.sharedService.dataEvent.subscribe(() => { this.generateData(); });
+ sessionStorage.setItem('clusterType', this.isCluster);
}
/** smart table Header Colums @public */
@@ -115,8 +128,8 @@
name: { title: this.translateService.instant('NAME'), width: '20%', sortDirection: 'asc' },
identifier: { title: this.translateService.instant('IDENTIFIER'), width: '20%' },
version: { title: this.translateService.instant('K8VERSION'), width: '10%' },
- operationalState: {
- title: this.translateService.instant('OPERATIONALSTATE'), width: '15%', type: 'html',
+ state: {
+ title: this.translateService.instant('STATE'), width: '15%', type: 'html',
filter: {
type: 'list',
config: {
@@ -124,25 +137,35 @@
list: [
{ value: this.operationalStateFirstStep, title: this.operationalStateFirstStep },
{ value: this.operationalStateSecondStep, title: this.operationalStateSecondStep },
- { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep }
+ { value: this.operationalStateThirdStep, title: this.operationalStateThirdStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFourthStep },
+ { value: this.operationalStateThirdStep, title: this.operationalStateFifthStep }
]
}
},
valuePrepareFunction: (cell: K8SCLUSTERDATADISPLAY, row: K8SCLUSTERDATADISPLAY): string => {
- if (row.operationalState === this.operationalStateFirstStep) {
- return `<span class="icon-label" title="${row.operationalState}">
- <i class="fas fa-clock text-warning"></i>
- </span>`;
- } else if (row.operationalState === this.operationalStateSecondStep) {
- return `<span class="icon-label" title="${row.operationalState}">
- <i class="fas fa-check-circle text-success"></i>
- </span>`;
- } else if (row.operationalState === this.operationalStateThirdStep) {
- return `<span class="icon-label" title="${row.operationalState}">
- <i class="fas fa-times-circle text-danger"></i>
- </span>`;
+ if (row.state === this.operationalStateFirstStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-clock text-success"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateSecondStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-warning"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateThirdStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-spinner text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFourthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-danger"></i>
+ </span>`;
+ } else if (row.state === this.operationalStateFifthStep) {
+ return `<span class="icon-label" title="${row.state}">
+ <i class="fas fa-times-circle text-warning"></i>
+ </span>`;
} else {
- return `<span>${row.operationalState}</span>`;
+ return `<span>${row.state}</span>`;
}
}
},
@@ -182,13 +205,19 @@
public addK8sCluster(): void {
// eslint-disable-next-line security/detect-non-literal-fs-filename
const modalRef: NgbModalRef = this.modalService.open(K8sAddClusterComponent, { backdrop: 'static' });
+
+ if (this.isCluster === 'Registered') {
+ modalRef.componentInstance.profileType = 'Register';
+ } else {
+ modalRef.componentInstance.profileType = 'Manage';
+ }
modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
if (result) {
this.sharedService.callData();
}
}).catch((): void => {
// Catch Navigation Error
- });
+ });
}
/**
@@ -202,6 +231,7 @@
public generateK8sclusterData(k8sClusterdata: K8SCLUSTERDATA): K8SCLUSTERDATADISPLAY {
return {
name: k8sClusterdata.name,
+ state: k8sClusterdata.state,
identifier: k8sClusterdata._id,
operationalState: k8sClusterdata._admin.operationalState,
version: k8sClusterdata.k8s_version,
@@ -211,10 +241,28 @@
};
}
+ /** Change event @public */
+ public onChangeEvent(value: string): void {
+ if (value === 'Managed') {
+ this.isCluster = 'Managed';
+ } else {
+ this.isCluster = 'Registered';
+ }
+ sessionStorage.setItem('clusterType', value);
+ this.generateColumns();
+ this.generateSettings();
+ this.generateData();
+ }
+
/** Fetching the data from server to Load in the smarttable @protected */
protected generateData(): void {
this.isLoadingResults = true;
- this.restService.getResource(environment.K8SCLUSTER_URL).subscribe((k8sClusterDatas: K8SCLUSTERDATA[]) => {
+ if (this.isCluster === 'Registered') {
+ this.clusterUrl = environment.K8SCREATECLUSTER_URL + '?created=false';
+ } else {
+ this.clusterUrl = environment.K8SCREATECLUSTER_URL + '?created=true';
+ }
+ this.restService.getResource(this.clusterUrl).subscribe((k8sClusterDatas: K8SCLUSTERDATA[]) => {
this.k8sClusterData = [];
k8sClusterDatas.forEach((k8sClusterdata: K8SCLUSTERDATA) => {
const k8sClusterDataObj: K8SCLUSTERDATADISPLAY = this.generateK8sclusterData(k8sClusterdata);