Skip to content
Snippets Groups Projects
Commit 8fcba71c authored by pgiertych's avatar pgiertych
Browse files

Merge branch 'develop' into 151-the-remove-bulk-domain-deployment-option-does-not-work

parents 9baf6c46 62c4806e
Branches
Tags
2 merge requests!32Resolve "Improve sorting in the application list view",!3151 the remove bulk domain deployment option does not work
Showing
with 142 additions and 41 deletions
name: Build docker image with tag latest name: Build docker image with appropriate tag
on: on:
push: push:
branches: branches:
- develop - develop
release:
types: [released]
jobs: jobs:
build_docker_image: build_docker_image:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: Determine Docker Tag
id: docker_tag
run: |
GIT_EVENT=${{ github.event_name }}
GIT_BRANCH_NAME=${GITHUB_REF##*/}
if [[ $GIT_EVENT == 'push' && $GIT_BRANCH_NAME == 'develop' ]]; then
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
elif [[ $GIT_EVENT == 'release' ]]; then
GIT_TAG_NAME=${{ github.event.release.tag_name }}
echo "DOCKER_TAG=$(echo $GIT_TAG_NAME | cut -c 2-)" >> $GITHUB_ENV
fi
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
...@@ -26,6 +40,7 @@ jobs: ...@@ -26,6 +40,7 @@ jobs:
- name: Build image and push to Artifactory - name: Build image and push to Artifactory
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: .
push: true push: true
tags: | tags: |
${{ secrets.DOCKER_REPOSITORY_LOCAL }}:latest ${{ secrets.DOCKER_REPOSITORY_LOCAL }}:${{ env.DOCKER_TAG }}
\ No newline at end of file \ No newline at end of file
...@@ -5,7 +5,7 @@ plugins { ...@@ -5,7 +5,7 @@ plugins {
id "org.sonarqube" version "3.2.0" id "org.sonarqube" version "3.2.0"
} }
version = '1.6.0-SNAPSHOT' version = '1.6.0'
task buildGUI(type: Exec) { task buildGUI(type: Exec) {
println 'Building using Angular CLI' println 'Building using Angular CLI'
......
...@@ -224,7 +224,7 @@ ...@@ -224,7 +224,7 @@
<td>{{getAppInstanceName(response)}}</td> <td>{{getAppInstanceName(response)}}</td>
<td>{{getDomainCodeName(response)}}</td> <td>{{getDomainCodeName(response)}}</td>
<td style="width: 5%" class="text-right"> <td style="width: 5%" class="text-right">
<span *ngif="response?.details['appInstanceId'] !==null" class="dropdown"> <span *ngif="response.type === 'APPLICATION' && response?.details['appInstanceId'] !== undefined" class="dropdown">
<a style="display: inline-block" class="dropdown-toggle " aria-expanded="false" aria-haspopup="true" <a style="display: inline-block" class="dropdown-toggle " aria-expanded="false" aria-haspopup="true"
data-toggle="dropdown" href="#" role="button"> data-toggle="dropdown" href="#" role="button">
<em class="fas fa-cog icon-black icon-bigger"></em> <em class="fas fa-cog icon-black icon-bigger"></em>
......
import {Component, OnDestroy, OnInit} from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import {BulkDeployment} from '../../../model/bulk-deployment'; import {BulkDeployment, BulkDeploymentState} from '../../../model/bulk-deployment';
import {AppdeploymentService} from '../appdeployment.service'; import {AppdeploymentService} from '../appdeployment.service';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {BulkResponse, BulkType} from '../../../model/bulk-response'; import {BulkResponse, BulkType} from '../../../model/bulk-response';
...@@ -55,6 +55,10 @@ export class BulkViewComponent implements OnInit, OnDestroy { ...@@ -55,6 +55,10 @@ export class BulkViewComponent implements OnInit, OnDestroy {
return entry?.details['appInstanceId'] return entry?.details['appInstanceId']
} }
public iSWorkingInstance(entry: BulkResponse) {
return entry?.state === BulkDeploymentState.COMPLETED || entry?.state.toString() == 'COMPLETED'
}
public getAppInstanceName(entry: BulkResponse) { public getAppInstanceName(entry: BulkResponse) {
return entry?.details['appInstanceName'] return entry?.details['appInstanceName']
} }
......
...@@ -21,18 +21,10 @@ export class DomainAnnotationsComponent implements OnInit { ...@@ -21,18 +21,10 @@ export class DomainAnnotationsComponent implements OnInit {
public handleAnnotationsUpdate(event: any ) { public handleAnnotationsUpdate(event: any ) {
console.warn(event) console.warn(event)
this.domainService.addAnnotations(event).subscribe(_ => {
this.annotations = this.domainService.getAnnotations();
})
} }
public handleDelete(key: string) { public handleDelete(key: string) {
console.warn("trigger delete for", key); console.warn("trigger delete for", key);
this.domainService.deleteAnnotation(key).subscribe(_ => {
this.annotations = this.domainService.getAnnotations();
})
} }
} }
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
<div *ngIf="isInMode(ComponentMode.CREATE)" > <div *ngIf="isInMode(ComponentMode.CREATE)" >
<app-domain-namespace-annotations [annotationRead]="annotations" (annotations)="handleAnnotationsChange($event)"></app-domain-namespace-annotations> <app-domain-namespace-annotations [annotationRead]="annotations" (annotations)="handleAnnotationsChange($event)" (trigerDelete)="handleAnnotationDelete($event)"></app-domain-namespace-annotations>
</div> </div>
<div *ngIf="isInMode(ComponentMode.VIEW)" class="panel panel-default"> <div *ngIf="isInMode(ComponentMode.VIEW)" class="panel panel-default">
......
...@@ -16,6 +16,7 @@ import {CustomerNetwork} from '../../../model/customernetwork'; ...@@ -16,6 +16,7 @@ import {CustomerNetwork} from '../../../model/customernetwork';
import {MinLengthDirective} from '../../../directive/min-length.directive'; import {MinLengthDirective} from '../../../directive/min-length.directive';
import {MaxLengthDirective} from '../../../directive/max-length.directive'; import {MaxLengthDirective} from '../../../directive/max-length.directive';
import { KeyValue } from '../../../model/key-value'; import { KeyValue } from '../../../model/key-value';
import { DomainAnnotation } from '../../../model/domain-annotation';
@Component({ @Component({
...@@ -46,7 +47,7 @@ export class DomainComponent extends BaseComponent implements OnInit { ...@@ -46,7 +47,7 @@ export class DomainComponent extends BaseComponent implements OnInit {
public displayCustomerNetworksSection = false; public displayCustomerNetworksSection = false;
public annotations : Observable<KeyValue[]> = of([]); public annotations : Observable<DomainAnnotation[]> = of([]);
constructor(public domainService: DomainService, constructor(public domainService: DomainService,
protected userService: UserService, protected userService: UserService,
...@@ -171,10 +172,15 @@ export class DomainComponent extends BaseComponent implements OnInit { ...@@ -171,10 +172,15 @@ export class DomainComponent extends BaseComponent implements OnInit {
this.domain.domainDcnDetails.customerNetworks.push(new CustomerNetwork()); this.domain.domainDcnDetails.customerNetworks.push(new CustomerNetwork());
} }
public handleAnnotationsChange(event: KeyValue[]){ public handleAnnotationsChange(event: DomainAnnotation[]){
this.domain.annotations = event; this.domain.annotations = event;
console.log("Updated domain annotations", this.domain.annotations) console.log("Updated domain annotations", this.domain.annotations)
} }
public handleAnnotationDelete(event : number) {
this.domain.annotations = this.domain.annotations.filter(val => val.id !== event)
console.log("Updated domain annotations", this.domain.annotations)
}
} }
export class DomainAnnotation {
public id: number;
public key : string;
public value : string;
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ import {DomainTechDetails} from './domaintechdetails'; ...@@ -3,6 +3,7 @@ import {DomainTechDetails} from './domaintechdetails';
import {DomainApplicationStatePerDomain} from './domainapplicationstateperdomain'; import {DomainApplicationStatePerDomain} from './domainapplicationstateperdomain';
import {DomainGroup} from './domaingroup'; import {DomainGroup} from './domaingroup';
import {KeyValue} from './key-value'; import {KeyValue} from './key-value';
import { DomainAnnotation } from './domain-annotation';
export class Domain { export class Domain {
public id: number = undefined; public id: number = undefined;
...@@ -14,5 +15,5 @@ export class Domain { ...@@ -14,5 +15,5 @@ export class Domain {
public applicationStatePerDomain: DomainApplicationStatePerDomain[] = []; public applicationStatePerDomain: DomainApplicationStatePerDomain[] = [];
public groups: DomainGroup[] = []; public groups: DomainGroup[] = [];
public deleted: boolean; public deleted: boolean;
public annotations: KeyValue[] = []; public annotations: DomainAnnotation[] = [];
} }
...@@ -10,6 +10,7 @@ import {Domain} from '../model/domain'; ...@@ -10,6 +10,7 @@ import {Domain} from '../model/domain';
import {User} from '../model'; import {User} from '../model';
import {DomainGroup} from '../model/domaingroup'; import {DomainGroup} from '../model/domaingroup';
import { KeyValue } from '../model/key-value'; import { KeyValue } from '../model/key-value';
import { DomainAnnotation } from '../model/domain-annotation';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
...@@ -115,15 +116,19 @@ export class DomainService extends GenericDataService { ...@@ -115,15 +116,19 @@ export class DomainService extends GenericDataService {
return this.put(this.url + 'group/' + id, domainGroup); return this.put(this.url + 'group/' + id, domainGroup);
} }
public getAnnotations(): Observable<KeyValue[]> { public getAnnotations(): Observable<DomainAnnotation[]> {
return this.get<KeyValue[]>(this.url + 'annotations') return this.get<DomainAnnotation[]>(this.url + 'annotations')
} }
public addAnnotations(annotations: KeyValue[]): Observable<void> { public addAnnotations(annotation: KeyValue): Observable<void> {
return this.post(this.url + 'annotations', annotations) return this.post(this.url + 'annotations', annotation)
} }
public deleteAnnotation(key: string) : Observable<void>{ public deleteAnnotation(id: number) : Observable<void>{
return this.delete(`${this.url}annotations/${key}`,) return this.delete(`${this.url}annotations/${id}`)
}
public updateAnnotation(annotation: DomainAnnotation): Observable<void> {
return this.put(`${this.url}annotations/${annotation.id}`, annotation)
} }
} }
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
<div class="grid flex flex-grow-1 mt-4 mb-2" *ngFor="let kv of keyValue"> <div class="grid flex flex-grow-1 mt-4 mb-2" *ngFor="let kv of keyValue">
<div class="flex grid flex-grow-1"> <div class="flex grid flex-grow-1">
<div class="col-4"> <div class="col-4">
<input pInputText type="text" [disabled]="getReadOnlyValue(kv.key)" (focusout)="emmitValue(kv.key)" [(ngModel)]="kv.key" class="flex flex-grow-1" style="width: 100%" [ngClass]="{ 'border-red': isKeyNotUnique(kv.key)}"> <input pInputText type="text" (focusout)="emmitValue(kv)" [(ngModel)]="kv.key" class="flex flex-grow-1" style="width: 100%" [ngClass]="{ 'border-red': isKeyNotUnique(kv.key)}">
</div> </div>
<div class="col-6"> <div class="col-6">
<input pInputText type="text" (focusout)="emmitValue()" [(ngModel)]="kv.value" class="flex flex-grow-1" style="width: 100%"> <input pInputText type="text" (focusout)="emmitValue(kv)" [(ngModel)]="kv.value" class="flex flex-grow-1" style="width: 100%">
</div> </div>
<div class="col-2 flex justify-content-end"> <div class="col-2 flex justify-content-end">
<button type="button" class="btn btn-danger" (click)="deleteAnnotation(kv.key)">Delete</button> <button type="button" class="btn btn-danger" (click)="deleteAnnotation(kv.id)">Delete</button>
</div> </div>
</div> </div>
</div> </div>
...@@ -37,11 +37,31 @@ ...@@ -37,11 +37,31 @@
<nmaas-modal> <nmaas-modal>
<div class="nmaas-modal-header">{{'DOMAINS.LIST.GROUP' | translate}}</div> <div class="nmaas-modal-header">{{'DOMAINS.ANNOTATIONS.ADD' | translate}}</div>
<div class="nmaas-modal-body" style="height: 300px"> <div class="nmaas-modal-body" style="height: 200px">
<div class="grid flex flex-grow-1">
<div class="col-4">
{{'DOMAINS.ANNOTATIONS.KEY' | translate}}
</div>
<div class="col-6">
{{'DOMAINS.ANNOTATIONS.VALUE' | translate}}
</div>
</div>
<div class="flex grid flex-grow-1">
<div class="col-4">
<input pInputText type="text" [(ngModel)]="newAnnotations.key" class="flex flex-grow-1" style="width: 100%" [ngClass]="{ 'border-red': isKeyNotUniqueAdd(newAnnotations.key)}">
</div>
<div class="col-6">
<input pInputText type="text" [(ngModel)]="newAnnotations.value" class="flex flex-grow-1" style="width: 100%">
</div>
</div>
</div> </div>
<div class="nmaas-modal-footer"> <div class="nmaas-modal-footer">
<button type="button" class="btn btn-default" (click)="modal.hide()">{{'APP_CHANGE_STATE_MODAL.CANCEL_BUTTON' | translate}}</button>
<button type="button" class="btn btn-primary" (click)="closeModal()" [disabled]="isKeyNotUniqueAdd(newAnnotations.key)">{{'SHARED.ADD' | translate}}</button>
</div> </div>
</nmaas-modal> </nmaas-modal>
...@@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; ...@@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DomainNamespaceAnnotationsComponent } from './domain-namespace-annotations.component'; import { DomainNamespaceAnnotationsComponent } from './domain-namespace-annotations.component';
import {TranslateFakeLoader, TranslateLoader, TranslateModule} from '@ngx-translate/core'; import {TranslateFakeLoader, TranslateLoader, TranslateModule} from '@ngx-translate/core';
import { HttpClientTestingModule } from '@angular/common/http/testing';
describe('DomainNamespaceAnnotationsComponent', () => { describe('DomainNamespaceAnnotationsComponent', () => {
let component: DomainNamespaceAnnotationsComponent; let component: DomainNamespaceAnnotationsComponent;
...@@ -11,6 +12,7 @@ describe('DomainNamespaceAnnotationsComponent', () => { ...@@ -11,6 +12,7 @@ describe('DomainNamespaceAnnotationsComponent', () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ DomainNamespaceAnnotationsComponent ], declarations: [ DomainNamespaceAnnotationsComponent ],
imports: [ imports: [
HttpClientTestingModule,
TranslateModule.forRoot({ TranslateModule.forRoot({
loader: { loader: {
provide: TranslateLoader, provide: TranslateLoader,
......
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {KeyValue} from '../../model/key-value'; import {KeyValue} from '../../model/key-value';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { DomainAnnotation } from '../../model/domain-annotation';
import { ModalComponent } from '../modal';
import { DomainService } from '../../service';
@Component({ @Component({
selector: 'app-domain-namespace-annotations', selector: 'app-domain-namespace-annotations',
...@@ -9,27 +12,36 @@ import { Observable, of } from 'rxjs'; ...@@ -9,27 +12,36 @@ import { Observable, of } from 'rxjs';
}) })
export class DomainNamespaceAnnotationsComponent implements OnInit { export class DomainNamespaceAnnotationsComponent implements OnInit {
@ViewChild(ModalComponent, {static: true})
public readonly modal: ModalComponent;
@Input() @Input()
public annotationRead: Observable<KeyValue[]> = of([]); public annotationRead: Observable<DomainAnnotation[]> = of([]);
@Input() @Input()
public globalSettings: boolean = false; public globalSettings: boolean = false;
@Output() @Output()
public annotations: EventEmitter<KeyValue[]> = new EventEmitter<KeyValue[]>(); public annotations: EventEmitter<DomainAnnotation[]> = new EventEmitter<DomainAnnotation[]>();
@Output() @Output()
public trigerDelete: EventEmitter<string> = new EventEmitter<string>(); public trigerDelete: EventEmitter<string> = new EventEmitter<string>();
public keyValue: KeyValue[] = [] public keyValue: DomainAnnotation[] = []
private keySetNotUnique: string[] = []; private keySetNotUnique: string[] = [];
public isKeysUnique = true; public isKeysUnique = true;
public isKeyValuePresent =true; public isKeyValuePresent =true;
public newAnnotations : DomainAnnotation = new DomainAnnotation();
public reaOnlyMap = new Map<string, boolean>(); public reaOnlyMap = new Map<string, boolean>();
public constructor(private readonly domainService: DomainService) {
}
ngOnInit(): void { ngOnInit(): void {
console.warn("annotations", this.annotationRead) console.warn("annotations", this.annotationRead)
this.annotationRead.subscribe(annotation =>{ this.annotationRead.subscribe(annotation =>{
...@@ -40,14 +52,24 @@ export class DomainNamespaceAnnotationsComponent implements OnInit { ...@@ -40,14 +52,24 @@ export class DomainNamespaceAnnotationsComponent implements OnInit {
}) })
} }
public emmitValue(key: string = "") { public emmitValue(keyValue: DomainAnnotation) {
this.checkDuplicate() this.checkDuplicate()
if ( this.isKeysUnique && this.isKeyValuePresent) { if ( this.isKeysUnique && this.isKeyValuePresent) {
this.annotations.emit(this.keyValue); this.annotations.emit(this.keyValue);
} }
if(key !== "") {
this.reaOnlyMap.set(key, true); if(keyValue !== null) {
if(keyValue.key !== "") {
this.reaOnlyMap.set(keyValue.key, true);
}
if(this.globalSettings) {
this.domainService.updateAnnotation(keyValue).subscribe(_=> {
console.warn("Updated annotation", keyValue)
})
}
} }
} }
public checkDuplicate() { public checkDuplicate() {
...@@ -74,13 +96,17 @@ export class DomainNamespaceAnnotationsComponent implements OnInit { ...@@ -74,13 +96,17 @@ export class DomainNamespaceAnnotationsComponent implements OnInit {
} }
addAnnotation() { addAnnotation() {
this.keyValue.push(new KeyValue()) this.newAnnotations = new DomainAnnotation();
this.modal.show();
} }
deleteAnnotation(key: any) { deleteAnnotation(id: any) {
this.keyValue = this.keyValue.filter(val => val.key !== key) this.keyValue = this.keyValue.filter(val => val.id !== id)
if(this.globalSettings) { this.trigerDelete.emit(id);
this.trigerDelete.emit(key); if(this.globalSettings){
this.domainService.deleteAnnotation(id).subscribe(_=>{
this.annotationRead = this.domainService.getAnnotations();
})
} }
} }
...@@ -88,10 +114,35 @@ export class DomainNamespaceAnnotationsComponent implements OnInit { ...@@ -88,10 +114,35 @@ export class DomainNamespaceAnnotationsComponent implements OnInit {
return this.keySetNotUnique.some(val => val === key) return this.keySetNotUnique.some(val => val === key)
} }
public isKeyNotUniqueAdd(key: string) {
return this.keyValue.some(val => val.key === key)
}
public getReadOnlyValue(key: string) { public getReadOnlyValue(key: string) {
if(this.reaOnlyMap.has(key)){ if(this.reaOnlyMap.has(key)){
return this.reaOnlyMap.get(key); return this.reaOnlyMap.get(key);
} else return false; } else return false;
} }
public closeModal() {
if(this.globalSettings) {
this.domainService.addAnnotations(this.newAnnotations).subscribe(_ => {
console.log("Send request to create new annotations", this.newAnnotations)
this.newAnnotations = new DomainAnnotation();
this.annotationRead = this.domainService.getAnnotations();
this.triggerRefresh();
})
} else {
this.keyValue.push(this.newAnnotations)
this.newAnnotations = new DomainAnnotation();
}
this.emmitValue(null);
this.modal.hide();
}
public triggerRefresh() {
this.annotationRead.subscribe(annotation =>{
this.keyValue = annotation;
})
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment