Skip to content
Snippets Groups Projects
Commit bb241bbb authored by Joanna Kaźmierczak's avatar Joanna Kaźmierczak
Browse files

Merge remote-tracking branch 'origin/develop' into 272-improve-new-layout

# Conflicts:
#	src/app/shared/admin/clusters/manager/manager.component.html
#	src/app/shared/admin/clusters/manager/manager.component.ts
parents f2a140dd 0a9c7e7b
No related branches found
No related tags found
1 merge request!188Resolve "Improve new layout"
Showing
with 606 additions and 27 deletions
......@@ -28,7 +28,7 @@ sonar:
build_and_push_latest_image:
stage: build
image: korvoj/docker-git:26.1.3
image: korvoj/docker-git:26.1.4
only:
- develop
variables:
......@@ -55,7 +55,7 @@ build_and_push_alfa_image:
build_and_push_release_image:
stage: build
image: korvoj/docker-git:26.1.3
image: korvoj/docker-git:26.1.4
only:
- tags
script:
......
......@@ -34,6 +34,7 @@ import {SplitButtonModule} from 'primeng/splitbutton';
import {MenuModule} from 'primeng/menu';
import { AdminLeftMenuComponent } from './shared/admin-left-menu/admin-left-menu.component';
import {AccordionModule} from 'primeng/accordion';
import { RecaptchaVisibilityService } from './service/recaptcha-visibility.service';
export function appConfigFactory(config: AppConfigService) {
return function create() {
......@@ -98,6 +99,7 @@ export const jwtOptionsFactory = (appConfig: AppConfigService) => ({
providers: [
AuthGuard,
AuthService,
RecaptchaVisibilityService,
AppConfigService,
provideZxvbnServiceForPSM(),
{
......
......@@ -2,8 +2,14 @@ import {Route} from "@angular/router";
import {AuthGuard} from "../../../auth/auth.guard";
import {RoleGuard} from "../../../auth/role.guard";
import {ConfigurationDetailsComponent} from "./index";
import { WebhookListComponent } from "../webhook/webhook-list/webhook-list.component";
import { WebhookDetailsComponent } from "../webhook/webhook-details/webhook-details.component";
export const ConfigurationRoutes: Route[] = [
{path: 'configuration', component: ConfigurationDetailsComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} },
{path: 'webhooks', component: WebhookListComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} },
{path: 'webhooks/:id', component: WebhookDetailsComponent, canActivate: [AuthGuard, RoleGuard],
data:{roles: ['ROLE_SYSTEM_ADMIN']} }
];
<div class="">
<div class="background-section">
<h4 style="font-size:15px; font-weight: bold">{{ 'WEBHOOKS.TITLE' | translate }}</h4>
<div class="panel-body">
<form *ngIf="webhook" (submit)="submit()" class="form-horizontal" #webhookForm="ngForm">
<div class="panel-default panel-heading">{{ 'CLUSTERS.GENERAL' | translate }} </div>
<div class="panel-body">
<div class="form-group">
<label for="clusterId" class="col-sm-2 control-label">{{ 'WEBHOOKS.ID' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterId" name="clusterId"
[(ngModel)]="webhook.id" [disabled]="true">
</div>
</div>
</div>
<div class="form-group">
<label for="clusterName" class="col-sm-2 control-label">{{ 'WEBHOOKS.NAME' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterName" name="clusterName"
[(ngModel)]="webhook.name" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="targetUrl" class="col-sm-2 control-label">{{ 'WEBHOOKS.TARGEt_URL' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="targetUrl" name="targetUrl"
[(ngModel)]="webhook.targetUrl" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="clusterDescription" class="col-sm-2 control-label">{{ 'WEBHOOKS.TYPE' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="clusterDescription" name="clusterDescription"
placeholder="{{webhook.eventType | translate}}" [disabled]="true">
</div>
</div>
</div>
<div class="form-group">
<label for="token" class="col-sm-2 control-label">{{ 'WEBHOOKS.TOKEN' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="token" name="token"
[(ngModel)]="webhook.tokenValue" [disabled]="false">
</div>
</div>
</div>
<div class="form-group">
<label for="auth" class="col-sm-2 control-label">{{ 'WEBHOOKS.AUTH' | translate }}</label>
<div class="col-sm-10">
<div class="col-sm-10">
<input type="text" class="form-control" id="auth" name="auth"
[(ngModel)]="webhook.authorizationHeader" [disabled]="false">
</div>
</div>
</div>
<div class="flex justify-content-end">
<button [disabled]="!webhookForm.form.valid" type="submit" class="btn btn-primary"
type="submit">{{ 'PORTAL_CONFIGURATION.SUBMIT_BUTTON' | translate }}</button>
</div>
</div>
</form>
</div>
</div>
</div>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WebhookDetailsComponent } from './webhook-details.component';
import { WebhookService } from '../../../../service/webhook.service';
import { ActivatedRoute, Router } from '@angular/router';
import { of } from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Webhook } from '../../../../model/webhook';
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { FormsModule } from '@angular/forms';
class MockWebhookService {
getOne = jasmine.createSpy().and.returnValue(of({ id: 1, name: 'Test', eventType: 'DOMAIN_CREATION', targetUrl: 'http://test' }));
update = jasmine.createSpy().and.returnValue(of({ id: 1, name: 'Updated', eventType: 'DOMAIN_CREATION', targetUrl: 'http://test' }));
}
class MockActivatedRoute {
params = of({ id: 1 });
}
class MockRouter {}
describe('WebhookDetailsComponent', () => {
let component: WebhookDetailsComponent;
let fixture: ComponentFixture<WebhookDetailsComponent>;
let service: MockWebhookService;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [WebhookDetailsComponent],
imports: [
FormsModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateFakeLoader
}
}),
],
providers: [
{ provide: WebhookService, useClass: MockWebhookService },
{ provide: ActivatedRoute, useClass: MockActivatedRoute },
{ provide: Router, useClass: MockRouter }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
fixture = TestBed.createComponent(WebhookDetailsComponent);
component = fixture.componentInstance;
service = TestBed.inject(WebhookService) as any;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should initialize and fetch webhook by id', () => {
expect(component.webhooksId).toBe(1);
expect(service.getOne).toHaveBeenCalledWith(1);
expect(component.webhook).toBeDefined();
expect(component.webhook.id).toBe(1);
});
});
import { Component, OnInit } from '@angular/core';
import { WebhookService } from '../../../../service/webhook.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Webhook } from '../../../../model/webhook';
import { BaseComponent } from '../../../../shared/common/basecomponent/base.component';
@Component({
selector: 'app-webhook-details',
templateUrl: './webhook-details.component.html',
styleUrl: './webhook-details.component.css'
})
export class WebhookDetailsComponent extends BaseComponent implements OnInit {
public webhooksId: number;
public webhook: Webhook;
constructor(private service: WebhookService,
public router: Router,
private route: ActivatedRoute) {
super();
}
ngOnInit(): void {
this.route.params.subscribe(params => {
this.webhooksId = +params['id'];
this.service.getOne(this.webhooksId).subscribe(result => {
console.log(result);
this.webhook = result;
} )
})
}
public submit(): void {
console.log(this.webhook);
this.service.update(this.webhook).subscribe(result => {
console.log(result);
this.webhook = result;
});
}
}
<div style="display: flex; align-items: center; margin-top:20px">
<div style="margin-right:20px">
<div >
<button class="btn btn-primary" (click)="openModal()">{{'WEBHOOKS.NEW' | translate}}</button>
</div>
</div>
<div class="flex" style="margin-right:20px">
</div>
</div>
<h4 class="header">{{ 'WEBHOOKS.TITLE' | translate }}</h4>
<div class="background-section">
<p-table
[value]="webkooks"
[paginator]="true"
[rows]="maxItemsOnPage"
[rowsPerPageOptions]="[15, 20, 25, 30, 50]"
[responsiveLayout]="'scroll'">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="id" id="id"> {{ 'WEBHOOKS.ID' | translate }}
<p-sortIcon field="id"></p-sortIcon>
</th>
<th pSortableColumn="name" id="name"> {{ 'WEBHOOKS.NAME' | translate }}
<p-sortIcon field="name"></p-sortIcon>
</th>
<th pSortableColumn="url" id="url"> {{ 'WEBHOOKS.TARGET_URL' | translate }}
<p-sortIcon field="url"></p-sortIcon>
</th>
<th pSortableColumn="type" id="type"> {{ 'WEBHOOKS.TYPE' | translate }}
<p-sortIcon field="type"></p-sortIcon>
</th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-webhook>
<tr>
<td [routerLink]="[webhook.id]">{{webhook.id}}</td>
<td>{{webhook.name}}</td>
<td>{{('WEBHOOKS.' + webhook.eventType.toString().toUpperCase() ) | translate}}</td>
<td>{{webhook.targetUrl}}</td>
<td class="text-right">
<span class="dropdown">
<a style="display: inline-block" class="dropdown-toggle" aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button">
<em class="pi pi-cog" style="font-size: 1.8rem; color: var(--l-text-color)"></em>
</a>
<ul class="dropdown-menu pull-right-drop" >
<li><a [routerLink]="[ webhook.id]" class="">
{{ 'WEBHOOKS.DETAILS' | translate }}</a>
</li>
</ul>
</span>
</td>
</tr>
</ng-template>
</p-table>
</div>
<nmaas-modal >
<div class="nmaas-modal-header">{{'WEBHOOKS.TITLE_SHORT' | translate}}</div>
<div class="nmaas-modal-body">
<div class="flex flex-column">
<div class="mt-4">
<label for="name">{{'WEBHOOKS.NAME' | translate}}</label>
<input id="name" type="text" class="form-control" [(ngModel)]="addedWebhook.name" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<label for="desc">{{'WEBHOOKS.TARGET_URL' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.targetUrl" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<label for="contactEmail">{{'WEBHOOKS.TYPE' | translate}}</label>
<select id="domain" #typeSelect class="form-control" (change)="onTypeSelect(typeSelect.value)" >
<option *ngFor="let t of type" [value]="t.name"
>{{t.name | translate}}
</option>
</select>
</div>
<div class="mt-4">
<label for="assignDomain">Auth required</label>
<input class="ml-2" type="checkbox" [(ngModel)]="authRequired" id="authRequired"/>
</div>
<div *ngIf="authRequired" class="mt-4">
<label for="desc">{{'WEBHOOKS.TOKEN' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.tokenValue" [ngModelOptions]="{standalone: true}">
</div>
<div *ngIf="authRequired" class="mt-4">
<label for="desc">{{'WEBHOOKS.AUTH' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedWebhook.authorizationHeader" [ngModelOptions]="{standalone: true}">
</div>
</div>
</div>
<div class="nmaas-modal-footer">
<button type="button" class="btn btn-primary" [disabled]=" addedWebhook?.name === null "(click)="closeModalAndSaveWebhook()"
pTooltip="Upload file is required before save" showDelay="2000" >{{'CLUSTERS.SAVE' | translate}}</button>
<button type="button" class="btn btn-secondary"
(click)="this.modal.hide()">{{'UNDEPLOY_MODAL.CANCEL_BUTTON' | translate}}</button>
</div>
</nmaas-modal>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { WebhookListComponent } from './webhook-list.component';
import { WebhookService } from '../../../../service/webhook.service';
import { of } from 'rxjs';
import { ModalComponent } from '../../../../shared';
import { Webhook, WebhookType } from '../../../../model/webhook';
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from '@ngx-translate/core';
class MockWebhookService {
getAll = jasmine.createSpy().and.returnValue(of([{ id: 1, name: 'Test', eventType: 'DOMAIN_CREATION', targetUrl: 'http://test' }]));
create = jasmine.createSpy().and.returnValue(of({}));
}
class MockModalComponent {
show = jasmine.createSpy();
hide = jasmine.createSpy();
}
describe('WebhookListComponent', () => {
let component: WebhookListComponent;
let fixture: ComponentFixture<WebhookListComponent>;
let service: MockWebhookService;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [WebhookListComponent],
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateFakeLoader
}
}),
],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: WebhookService, useClass: MockWebhookService }
]
})
.overrideComponent(WebhookListComponent, {
set: {
providers: [],
}
})
.compileComponents();
fixture = TestBed.createComponent(WebhookListComponent);
component = fixture.componentInstance;
service = TestBed.inject(WebhookService) as any;
component.modal = new MockModalComponent() as any;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have a defined component instance', () => {
expect(component).toBeDefined();
});
it('should render the component', () => {
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled).toBeTruthy();
});
it('should refresh list and set webkooks', () => {
component.refreshList();
expect(service.getAll).toHaveBeenCalled();
fixture.detectChanges();
expect(component.webkooks.length).toBeGreaterThan(0);
});
it('should open modal and set default event type', () => {
component.openModal();
expect(component.addedWebhook.eventType).toBe(WebhookType.DOMAIN_CREATION);
expect(component.modal.show).toHaveBeenCalled();
});
it('should call service.create and hide modal on closeModalAndSaveWebhook', () => {
component.addedWebhook = { name: 'Test', eventType: 'DOMAIN_CREATION', targetUrl: 'http://test' } as Webhook;
component.closeModalAndSaveWebhook();
expect(service.create).toHaveBeenCalledWith(component.addedWebhook);
expect(component.modal.hide).toHaveBeenCalled();
});
it('should set addedWebhook.eventType on type select', () => {
component.onTypeSelect('USER_ASSIGNMENT');
expect(component.addedWebhook.eventType).toBe('USER_ASSIGNMENT');
});
});
import { Component, OnInit, ViewChild } from '@angular/core';
import { Webhook, WebhookType } from '../../../../model/webhook';
import { ModalComponent } from '../../../../shared';
import { WebhookService } from '../../../../service/webhook.service';
@Component({
selector: 'app-webhook-list',
templateUrl: './webhook-list.component.html',
styleUrl: './webhook-list.component.css'
})
export class WebhookListComponent implements OnInit {
public webkooks: Webhook[] = [];
public addedWebhook: Webhook = new Webhook();
public maxItemsOnPage = 15;
public authRequired: boolean = false;
public type =[
{ name: "DOMAIN_CREATION", value: "DOMAIN_CREATION" },
{ name: "APPLICATION_DEPLOYMENT", value: "APPLICATION_DEPLOYMENT" },
{ name: "USER_ASSIGNMENT", value: "USER_ASSIGNMENT" },
{ name: "DOMAIN_GROUP_CHANGE", value: "DOMAIN_GROUP_CHANGE" }
]
@ViewChild(ModalComponent, { static: true })
public modal: ModalComponent;
constructor(private service: WebhookService) {
}
ngOnInit() {
this.refreshList();
}
public refreshList() {
this.service.getAll().subscribe(result => {
this.webkooks = result;
})
}
onTypeSelect(event: any) {
console.log(event);
this.addedWebhook.eventType = event;
}
public openModal() {
this.addedWebhook.eventType = WebhookType.DOMAIN_CREATION
this.modal.show();
}
public closeModalAndSaveWebhook() {
this.service.create(this.addedWebhook).subscribe(result => {
this.modal.hide();
this.refreshList();
});
}
}
......@@ -51,6 +51,9 @@ import { InputSwitchModule } from 'primeng/inputswitch';
import { OverlayPanelModule } from 'primeng/overlaypanel';
import { SidebarModule } from 'primeng/sidebar';
import { ProgressBarModule } from 'primeng/progressbar';
import { WebhookDetailsComponent } from './admin/webhook/webhook-details/webhook-details.component';
import { WebhookListComponent } from './admin/webhook/webhook-list/webhook-list.component';
import { WebhookService } from '../service/webhook.service';
......@@ -67,7 +70,9 @@ import { ProgressBarModule } from 'primeng/progressbar';
BulkViewComponent,
BulkAppListComponent,
BulkListComponent,
BulkSearchPipe
BulkSearchPipe,
WebhookDetailsComponent,
WebhookListComponent
],
imports: [
FormsModule,
......@@ -101,7 +106,7 @@ import { ProgressBarModule } from 'primeng/progressbar';
InputSwitchModule,
OverlayPanelModule,
SidebarModule,
ProgressBarModule
ProgressBarModule,
],
exports: [
AppMarketComponent,
......@@ -116,6 +121,7 @@ import { ProgressBarModule } from 'primeng/progressbar';
ClusterService,
SortService,
SessionService,
WebhookService
],
schemas: [
NO_ERRORS_SCHEMA,
......
......@@ -15,4 +15,6 @@ export class ClusterManager {
public externalNetworks: ClusterExtNetwork[]
public domainNames: string[];
public state : string;
public currentStateSince: Date;
public contactEmail: string;
}
\ No newline at end of file
export class Webhook {
public id: number = undefined;
public name: string = undefined;
public targetUrl: string = undefined;
public tokenValue: string = undefined;
public authorizationHeader: string = undefined;
public eventType: WebhookType = undefined;
}
export enum WebhookType {
DOMAIN_CREATION = "DOMAIN_CREATION",
APPLICATION_DEPLOYMENT = "APPLICATION_DEPLOYMENT",
USER_ASSIGNMENT = "USER_ASSIGNMENT",
DOMAIN_GROUP_CHANGE = "DOMAIN_GROUP_CHANGE",
}
\ No newline at end of file
......@@ -19,12 +19,15 @@ export class DomainService extends GenericDataService {
protected url: string;
protected urlGroups: string;
private updateRequiredFlag: boolean;
constructor(http: HttpClient, appConfig: AppConfigService) {
super(http, appConfig);
this.updateRequiredFlag = false;
this.url = this.appConfig.getApiUrl() + '/domains';
this.urlGroups = this.appConfig.getApiUrl() + '/groups';
}
public getGlobalDomainId(): number {
......@@ -93,35 +96,35 @@ export class DomainService extends GenericDataService {
// GROUPS
public getAllDomainGroups(): Observable<DomainGroup[]> {
return this.get<DomainGroup[]>(this.url + '/group');
return this.get<DomainGroup[]>(this.urlGroups);
}
public getDomainGroup(domainGroupId: number): Observable<DomainGroup> {
return this.get<DomainGroup>(this.url + '/group/' + domainGroupId);
return this.get<DomainGroup>(this.urlGroups + '/' + domainGroupId);
}
public deleteDomainGroup(domainGroupId: number): Observable<void> {
return this.delete<void>(this.url + '/group/' + domainGroupId);
return this.delete<void>(this.urlGroups + '/' + domainGroupId);
}
public addDomainsToGroup(groupCodeName: string, domainIds: number[]): Observable<DomainGroup> {
return this.post(this.url + '/group/' + groupCodeName, domainIds);
return this.post(this.urlGroups + '/' + groupCodeName, domainIds);
}
public deleteDomainFromGroup(groupId: number, domainId: number): Observable<DomainGroup> {
return this.patch(this.url + '/group/' + groupId, domainId);
return this.patch(this.urlGroups + '/' + groupId, domainId);
}
public createDomainGroup(domainGroup: DomainGroup): Observable<Id> {
return this.post(this.url + '/group', domainGroup);
return this.post(this.urlGroups , domainGroup);
}
public updateDomainGroup(domainGroup: DomainGroup, id: number): Observable<Id> {
return this.put(this.url + '/group/' + id, domainGroup);
return this.put(this.urlGroups+ "/" + id, domainGroup);
}
public updateDomainGroupManagers(managers: User[], id: number): Observable<DomainGroup> {
return this.put(this.url + '/group/members/' + id, managers);
return this.put(this.urlGroups + '/' + id + "/members", managers);
}
public getAnnotations(): Observable<DomainAnnotation[]> {
......
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class RecaptchaVisibilityService {
showBadge(): void {
const badge = document.querySelector('.grecaptcha-badge') as HTMLElement;
if (badge) {
badge.style.visibility = 'visible';
}
}
hideBadge(): void {
const badge = document.querySelector('.grecaptcha-badge') as HTMLElement;
if (badge) {
badge.style.visibility = 'hidden';
}
}
}
import { HttpClient } from '@angular/common/http';
import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import { AppConfigService } from './appconfig.service';
import { GenericDataService } from './genericdata.service';
import { Webhook } from '../model/webhook';
import { Id } from '../model';
@Injectable()
export class WebhookService extends GenericDataService {
protected url: string;
constructor(http: HttpClient, appConfig: AppConfigService) {
super(http, appConfig);
this.url = this.appConfig.getApiUrl() + '/webhooks';
}
public getAll() : Observable<Webhook[]> {
return this.get<Webhook[]>(this.url);
}
public create(webhook: Webhook) {
return this.post<Webhook, Id>(this.url, webhook);
}
public getOne(id: number) {
return this.get<Webhook>(this.url + '/' + id);
}
public update(webhook: Webhook) {
return this.put<Webhook, Webhook>(this.url + '/' + webhook.id, webhook);
}
}
import {Component, OnInit} from '@angular/core';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {AppConfigService, ChangelogService} from '../../service';
import {GitInfo} from '../../model/gitinfo';
import { RecaptchaVisibilityService } from '../../service/recaptcha-visibility.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
export class AboutComponent implements OnInit, OnDestroy {
public gitInfo: GitInfo;
constructor(private changelogService: ChangelogService,
private appConfigService: AppConfigService) {
private appConfigService: AppConfigService,
private readonly recaptcha: RecaptchaVisibilityService) {
}
ngOnInit() {
this.recaptcha.showBadge();
if (this.appConfigService.getShowGitInfo()) {
this.changelogService.getGitInfo().subscribe(info => this.gitInfo = info);
}
}
ngOnDestroy(): void {
this.recaptcha.hideBadge();
}
}
......@@ -59,7 +59,7 @@
</a>
<ul class="dropdown-menu pull-right-drop" >
<li><a [routerLink]="[ cluster.id]" class="">
{{ 'CLUSTERS.CONFIGURATION' | translate }}</a>
{{ 'CLUSTERS.DETAILS' | translate }}</a>
</li>
</ul>
</span>
......@@ -81,17 +81,30 @@
</div>
<div class="mt-4">
<label for="name">{{'CLUSTERS.DESCRIPTION' | translate}}</label>
<input id="name" type="text" class="form-control" [(ngModel)]="addedCluster.description" [ngModelOptions]="{standalone: true}">
<label for="desc">{{'CLUSTERS.DESCRIPTION' | translate}}</label>
<input id="desc" type="text" class="form-control" [(ngModel)]="addedCluster.description" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<label for="contactEmail">{{'CLUSTERS.CONTACT_MAIL' | translate}}</label>
<input id="contactEmail" type="text" class="form-control" [(ngModel)]="addedCluster.contactEmail" [ngModelOptions]="{standalone: true}">
</div>
<div class="mt-4">
<div>
<label for="assignDomain">Assign to domain? </label>
<input type="checkbox" [(ngModel)]="assignedDomain" (change)="onDomainChange($event)" id="assignDomain" />
</div>
<div class="mt-4" *ngIf="assignedDomain">
<label for="name">{{'CLUSTERS.DOMAIN' | translate}}</label>
<select id="domain" #domainSelect class="form-control" (change)="onDomainSelection(domainSelect.value)">
<select id="domain" #domainSelect class="form-control" (change)="onDomainSelection(domainSelect.value)" plaaceholder="testtesttest" >
<option *ngFor="let domain of domains" [value]="domain.name"
>{{domain.name}}
</option>
</select>
</div>
</div>
......@@ -106,7 +119,7 @@
<div class="nmaas-modal-footer">
<button type="button" class="btn btn-secondary"
(click)="this.modal.hide()">{{'UNDEPLOY_MODAL.CANCEL_BUTTON' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="updatedFile === null || addedCluster?.name === null || addedCluster?.description === null"(click)="closeModalAndSaveCluster()"
<button type="button" class="btn btn-primary" [disabled]="updatedFile === null || addedCluster?.name === null || addedCluster?.description === null"(click)="closeModalAndSaveCluster()"
pTooltip="Upload file is required before save" showDelay="2000" >{{'CLUSTERS.SAVE' | translate}}</button>
......
......@@ -14,8 +14,9 @@ export class ClusterManagerComponent {
public clusters: ClusterManager[] = [];
public addedCluster: ClusterManager = new ClusterManager();
public updatedFile : File = null;
public updatedFile: File = null;
public maxItemsOnPage = 15;
public assignedDomain: boolean = false;
public searchValue = '';
filteredClusters: ClusterManager[] = [];
......@@ -34,7 +35,7 @@ export class ClusterManagerComponent {
public saveFile(event: any) {
console.log(event);
this.updatedFile =event.files[0];
this.updatedFile = event.files[0];
}
public getAllClusters() {
......@@ -58,10 +59,23 @@ export class ClusterManagerComponent {
}
public onDomainSelection(event: any) {
console.log(event);
this.addedCluster.domainNames = [event]
}
public onDomainSelection(event: any) {
console.log(event);
this.addedCluster.domainNames = [event]
}
public openModal() {
if (this.domains.length > 0) {
this.addedCluster.domainNames = [this.domains[0].name];
}
this.modal.show();
}
public onDomainChange(event: any) {
console.log(event);
}
filterClusters() {
const value = this.searchValue?.toLowerCase() || '';
this.filteredClusters = this.clusters.filter(cluster =>
......@@ -70,5 +84,4 @@ export class ClusterManagerComponent {
cluster.id?.toString().includes(value)
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment