Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 8b12f332 authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

Implementation of metadata dialog, service group dialog,

parent 7f805399
No related branches found
No related tags found
No related merge requests found
Showing
with 537 additions and 294 deletions
......@@ -5,22 +5,20 @@ import {HttpClient, HttpClientModule} from '@angular/common/http';
import {FlexLayoutModule} from "@angular/flex-layout";
import {
MatButtonModule,
MatCardModule,
MatDatepickerModule,
MatDialogModule,
MatExpansionModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatSelectModule,
MatSidenavModule,
MatTooltipModule,
MatExpansionModule,
MatDatepicker,
MatCardModule,
MatDatepickerModule,
MatSlideToggleModule,
MatTab,
MatAccordion,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
} from '@angular/material';
import "hammerjs";
......@@ -72,9 +70,11 @@ import {DomainDetailsDialogComponent} from './domain/domain-details-dialog/domai
import {UserDetailsDialogComponent} from './user/user-details-dialog/user-details-dialog.component';
import {DownloadService} from './download/download.service';
import {UserService} from './user/user.service';
import {RoleService} from './security/role.service';
import {CertificateService} from './user/certificate.service';
import {GlobalLookups} from "./common/global-lookups";
import {ServiceGroupExtensionWizardDialogComponent} from "./service-group-edit/service-group-extension-wizard-dialog/service-group-extension-wizard-dialog.component";
import {ServiceMetadataWizardDialogComponent} from "./service-group-edit/service-metadata-wizard-dialog/service-metadata-wizard-dialog.component";
import {ConfirmationDialogComponent} from "./common/confirmation-dialog/confirmation-dialog.component";
@NgModule({
declarations: [
......@@ -92,11 +92,14 @@ import {GlobalLookups} from "./common/global-lookups";
SaveDialogComponent,
ServiceGroupMetadataDialogComponent,
CancelDialogComponent,
ConfirmationDialogComponent,
RowLimiterComponent,
DatePipe,
CapitalizeFirstPipe,
DefaultPasswordDialogComponent,
ServiceGroupDetailsDialogComponent,
ServiceGroupExtensionWizardDialogComponent,
ServiceMetadataWizardDialogComponent,
ColumnPickerComponent,
PageHelperComponent,
ClearInvalidDirective,
......@@ -110,9 +113,12 @@ import {GlobalLookups} from "./common/global-lookups";
AppComponent,
ServiceGroupMetadataDialogComponent,
ServiceGroupDetailsDialogComponent,
ServiceGroupExtensionWizardDialogComponent,
ServiceMetadataWizardDialogComponent,
DomainDetailsDialogComponent,
UserDetailsDialogComponent,
CancelDialogComponent,
ConfirmationDialogComponent,
SaveDialogComponent,
DefaultPasswordDialogComponent,
],
......@@ -128,6 +134,7 @@ import {GlobalLookups} from "./common/global-lookups";
MatDatepickerModule,
MatDialogModule,
MatTooltipModule,
MatToolbarModule,
MatMenuModule,
MatInputModule,
MatIconModule,
......@@ -155,7 +162,6 @@ import {GlobalLookups} from "./common/global-lookups";
DownloadService,
UserService,
CertificateService,
RoleService,
GlobalLookups,
DatePipe,
{
......
<div style="width: 500px;text-align: center">
<h1 mat-dialog-title>Do you want to cancel all unsaved operations?</h1>
<h1 mat-dialog-title>{{title}}</h1>
<div class="panel">{{description}}</div>
<div class="divTable">
<div class="divTableBody">
......
import {Component} from '@angular/core';
import {MatDialogRef} from '@angular/material';
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
@Component({
selector: 'app-cancel-dialog',
templateUrl: './cancel-dialog.component.html',
styleUrls: ['./cancel-dialog.component.css']
selector: 'app-confirmation-dialog',
templateUrl: './confirmation-dialog.component.html',
styleUrls: ['./confirmation-dialog.component.css']
})
export class CancelDialogComponent {
export class ConfirmationDialogComponent {
constructor(public dialogRef: MatDialogRef<CancelDialogComponent>) {
title: string;
description: string
constructor(public dialogRef: MatDialogRef<ConfirmationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
this.title=data.title;
this.description=data.description;
}
}
:host:before {
display: none !important;
content: '' !important;
margin-bottom: 0 !important;
}
.h1 {
margin-bottom: 0 !important;
}
......@@ -7,4 +7,5 @@ export interface SearchTableController {
delete(row);
newRow(): SearchTableEntity;
newDialog(config?: MatDialogConfig): MatDialogRef<any>;
dataSaved();
}
......@@ -41,3 +41,8 @@
padding: 0 !important;
margin: 0 !important;
}
.h1 {
margin-bottom: 0 !important;
}
<div fxLayout="column" style="position: absolute; top: 5px; bottom: 5px; left: 5px; right: 5px;">
<page-header flex id="{{id}}_header_id">{{title}}</page-header>
<h1 flex id="{{id}}_header_id" style="margin: 0 !important;">{{title}}</h1>
<div *ngIf="showSearchPanel" fxFlex="20" class="selectionCriteria">
<mat-card>
<mat-card-content>
......@@ -22,7 +21,7 @@
<div class="panel" fxFlex fxLayout="column">
<div class="group-filter-button" fxFlex="50px">
<span class="row-button">
<app-row-limiter [pageSizes]="rowLimiter.pageSizes"
<app-row-limiter [pageSizes]="rowLimiter.pageSizes"
(onPageSizeChanged)="changePageSize($event.value)"></app-row-limiter>
</span>
<!-- no need for this for SMP 4.1 <span class="column-filter-button">
......@@ -51,7 +50,7 @@
(page)="onPage($event)"
(sort)="onSort($event)"
[selected]="selected"
[selectionType]="'single'"
[selectionType]="'multi'"
(activate)="onActivate($event)"
(select)="onSelect($event)"
>
......
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {Component, Input, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {SearchTableResult} from './search-table-result.model';
import {Observable} from 'rxjs';
import {AlertService} from '../../alert/alert.service';
import {MatDialog, MatDialogRef} from '@angular/material';
import {ColumnPicker} from '../column-picker/column-picker.model';
import {RowLimiter} from '../row-limiter/row-limiter.model';
import {AlertComponent} from '../../alert/alert.component';
import {SearchTableController} from './search-table-controller';
import {finalize, map} from 'rxjs/operators';
import {finalize} from 'rxjs/operators';
import {SearchTableEntity} from './search-table-entity.model';
import {SearchTableEntityStatus} from './search-table-entity-status.model';
import {CancelDialogComponent} from '../cancel-dialog/cancel-dialog.component';
import {SaveDialogComponent} from '../save-dialog/save-dialog.component';
import {DownloadService} from '../../download/download.service';
import {HttpClient, HttpParams} from '@angular/common/http';
import {ConfirmationDialogComponent} from "../confirmation-dialog/confirmation-dialog.component";
@Component({
......@@ -61,6 +61,7 @@ export class SearchTableComponent implements OnInit {
offset: number = 0;
orderBy: string = null;
asc = false;
forceRefresh: boolean = false;
constructor(protected http: HttpClient,
protected alertService: AlertService,
......@@ -74,7 +75,7 @@ export class SearchTableComponent implements OnInit {
cellTemplate: this.rowIndex,
name: 'Index',
width: 50,
maxWidth:80,
maxWidth: 80,
sortable: false
};
......@@ -82,25 +83,25 @@ export class SearchTableComponent implements OnInit {
cellTemplate: this.rowActions,
name: 'Actions',
width: 250,
maxWidth:250,
maxWidth: 250,
sortable: false
};
this.columnExpandDetails= {
this.columnExpandDetails = {
cellTemplate: this.rowExpand,
name: ' ',
width: 40,
maxWidth:50,
maxWidth: 50,
sortable: false
};
// Add actions to last column
if (this.columnPicker) {
// prepend columns
if (!!this.tableRowDetailContainer){
if (!!this.tableRowDetailContainer) {
this.columnPicker.allColumns.unshift(this.columnExpandDetails);
this.columnPicker.selectedColumns.unshift(this.columnExpandDetails);
}
if (this.showIndexColumn){
if (this.showIndexColumn) {
this.columnPicker.allColumns.unshift(this.columnIndex);
this.columnPicker.selectedColumns.unshift(this.columnIndex);
}
......@@ -124,8 +125,8 @@ export class SearchTableComponent implements OnInit {
getTableDataEntries$(offset: number, pageSize: number, orderBy: string, asc: boolean): Observable<SearchTableResult> {
let params: HttpParams = new HttpParams()
.set('page', offset.toString())
.set('pageSize', pageSize.toString());
.set('page', offset.toString())
.set('pageSize', pageSize.toString());
for (let filterProperty in this.filter) {
......@@ -134,9 +135,8 @@ export class SearchTableComponent implements OnInit {
}
}
// TODO move to the HTTP service
this.loading = true;
return this.http.get<SearchTableResult>(this.url, { params }).pipe(
return this.http.get<SearchTableResult>(this.url, {params}).pipe(
finalize(() => {
this.loading = false;
})
......@@ -144,29 +144,48 @@ export class SearchTableComponent implements OnInit {
}
page(offset: number, pageSize: number, orderBy: string, asc: boolean) {
this.getTableDataEntries$(offset, pageSize, orderBy, asc).subscribe((result: SearchTableResult ) => {
if (this.safeRefresh) {
this.dialog.open(ConfirmationDialogComponent, {
data: {
title: "Not persisted data!",
description: "Action will refresh all data and not saved data will be lost. Do you wish to continue?"
}
}).afterClosed().subscribe(result => {
if (result) {
this.pageInternal(offset, pageSize, orderBy, asc);
}
})
} else {
this.pageInternal(offset, pageSize, orderBy, asc);
}
}
private pageInternal(offset: number, pageSize: number, orderBy: string, asc: boolean) {
this.getTableDataEntries$(offset, pageSize, orderBy, asc).subscribe((result: SearchTableResult) => {
this.offset = offset;
this.rowLimiter.pageSize = pageSize;
this.orderBy = orderBy;
this.asc = asc;
this.unselectRows();
this.forceRefresh=false;
this.count = result.count; // must be set else table can not calculate page numbers
this.rows = result.serviceEntities.map(serviceEntity => {
return {...serviceEntity,
return {
...serviceEntity,
status: SearchTableEntityStatus.PERSISTED,
deleted: false}
deleted: false
}
});
/*
if(this.count > AlertComponent.MAX_COUNT_CSV) {
this.alertService.error("Maximum number of rows reached for downloading CSV");
}*/
}, (error: any) => {
this.alertService.error("Error occurred:" + error);
});
}
onPage(event) {
this.page(event.offset, event.pageSize, this.orderBy, this.asc);
}
......@@ -177,8 +196,8 @@ export class SearchTableComponent implements OnInit {
onSelect({selected}) {
this.selected = [...selected];
if(this.editButtonEnabled) {
this.rowNumber = this.selected[0]["$$index"];
if (this.editButtonEnabled) {
this.rowNumber = this.rows.indexOf(this.selected[0]);
}
}
......@@ -203,14 +222,14 @@ export class SearchTableComponent implements OnInit {
onNewButtonClicked() {
const formRef: MatDialogRef<any> = this.searchTableController.newDialog({
data: { edit: false }
data: {edit: false}
});
formRef.afterClosed().subscribe(result => {
if (result) {
this.rows = [...this.rows, {...formRef.componentInstance.getCurrent()}];
//this.rows = this.rows.concat(formRef.componentInstance.current);
this.count++;
// this.searchtable.refresh();
// this.searchtable.refresh();
} else {
this.unselectRows();
}
......@@ -244,13 +263,13 @@ export class SearchTableComponent implements OnInit {
// this.isBusy = false;
// this.getUsers();
this.alertService.success('The operation \'update\' completed successfully.', false);
this.forceRefresh = true;
this.onRefresh();
this.searchTableController.dataSaved();
if (withDownloadCSV) {
this.downloadService.downloadNative(/*UserComponent.USER_CSV_URL TODO: use CSV url*/ '');
}
}, err => {
// this.isBusy = false;
// this.getUsers();
this.alertService.exception('The operation \'update\' not completed successfully.', err, false);
});
} else {
......@@ -295,6 +314,10 @@ export class SearchTableComponent implements OnInit {
return dirty;
}
get safeRefresh(): boolean {
return !(!this.submitButtonsEnabled || this.forceRefresh) ;
}
private editSearchTableEntity(rowNumber: number) {
const row = this.rows[rowNumber];
const formRef: MatDialogRef<any> = this.searchTableController.newDialog({
......@@ -305,23 +328,25 @@ export class SearchTableComponent implements OnInit {
const status = row.status === SearchTableEntityStatus.PERSISTED
? SearchTableEntityStatus.UPDATED
: row.status;
this.rows[rowNumber] = {...formRef.componentInstance.getCurrent(), status};
this.rows = [...this.rows];
this.rows[rowNumber] = {...formRef.componentInstance.getCurrent(), status};
this.rows = [...this.rows];
}
});
}
public updateTableRow(rowNumber:number, row:any, status:SearchTableEntityStatus ) {
public updateTableRow(rowNumber: number, row: any, status: SearchTableEntityStatus) {
this.rows[rowNumber] = {...row, status};
this.rows = [...this.rows];
}
public getRowNumber(row:any){
return this.rows.indexOf(row);
public getRowNumber(row: any) {
return this.rows.indexOf(row);
}
private editSearchTableEntityRow(row: SearchTableEntity) {
let rowNumber = this.rows.indexOf(row);
this.editSearchTableEntity(rowNumber);
let rowNumber = this.rows.indexOf(row);
this.editSearchTableEntity(rowNumber);
}
private deleteSearchTableEntities(rows: Array<SearchTableEntity>) {
......@@ -348,12 +373,12 @@ export class SearchTableComponent implements OnInit {
this.selected = [];
}
toggleExpandRow(selectedRow: any){
toggleExpandRow(selectedRow: any) {
//this.searchTableController.toggleExpandRow(selectedRow);
this.searchTable.rowDetail.toggleExpandRow(selectedRow);
}
onDetailToggle (event){
onDetailToggle(event) {
}
}
......@@ -3,14 +3,14 @@ import {MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material';
import {DomainDetailsDialogComponent} from './domain-details-dialog/domain-details-dialog.component';
import {DomainRo} from './domain-ro.model';
import {SearchTableEntityStatus} from '../common/search-table/search-table-entity-status.model';
import {UserDetailsDialogComponent} from "../user/user-details-dialog/user-details-dialog.component";
import {GlobalLookups} from "../common/global-lookups";
export class DomainController implements SearchTableController {
constructor(public dialog: MatDialog) {
constructor(protected lookups: GlobalLookups, public dialog: MatDialog) {
}
public showDetails(row: any) {
public showDetails( row: any) {
let dialogRef: MatDialogRef<DomainDetailsDialogComponent> = this.dialog.open(DomainDetailsDialogComponent);
dialogRef.afterClosed().subscribe(result => {
//Todo:
......@@ -40,4 +40,7 @@ export class DomainController implements SearchTableController {
status: SearchTableEntityStatus.NEW
}
}
public dataSaved() {
this.lookups.refreshDomainLookup();
}
}
......@@ -9,7 +9,10 @@
<input matInput placeholder="Domain Code (For WS API integration: the Domain property.)" name="domainCode" id="domainCode_id"
[formControl]="domainForm.controls['domainCode']" maxlength="255" required>
<div *ngIf="(!editMode && domainForm.controls['domainCode'].touched || editMode) && domainForm.controls['domainCode'].hasError('pattern')" style="color:red; font-size: 70%">
Domain could must contain only chars and numbers.
Domain code must contain only chars and numbers.
</div>
<div *ngIf="(!editMode && domainForm.controls['domainCode'].touched || editMode) && domainForm.controls['domainCode'].hasError('notInList')" style="color:red; font-size: 70%">
The Domain code already exists!
</div>
</mat-form-field>
<mat-form-field style="width:100%">
......@@ -18,6 +21,9 @@
<div *ngIf="(!editMode && domainForm.controls['smlSubdomain'].touched || editMode) && domainForm.controls['smlSubdomain'].hasError('pattern')" style="color:red; font-size: 70%">
SML domain must be valid DNS part (AlphaNumeric with optional char - or must be empty for peppol).
</div>
<div *ngIf="(!editMode && domainForm.controls['smlSubdomain'].touched || editMode) && domainForm.controls['smlSubdomain'].hasError('notInList')" style="color:red; font-size: 70%">
The SML subdomain is already defined!
</div>
</mat-form-field>
<mat-form-field style="width:100%">
<input matInput placeholder="Response signature Certificate" name="signatureKeyAlias" id="signatureKeyAlias_id"
......@@ -34,13 +40,15 @@
<input matInput placeholder="SML SMP identifier (SMP ID used for SML )" name="smlSmpId" id="smlSMPId_id"
[formControl]="domainForm.controls['smlSmpId']" maxlength="255" required>
<div *ngIf="(!editMode && domainForm.controls['smlSmpId'].touched || editMode) && domainForm.controls['smlSmpId'].hasError('pattern')" style="color:red; font-size: 70%">
SML SMP ID must be valid DNS part (AlphaNumeric with optional char -).
SML SMP ID must be valid DNS part (AlphaNumeric with optional char -)!
</div>
<div *ngIf="(!editMode && domainForm.controls['smlSmpId'].touched || editMode) && domainForm.controls['smlSmpId'].hasError('notInList')" style="color:red; font-size: 70%">
SML SMP ID already exists!
</div>
</mat-form-field>
<mat-form-field style="width:100%">
<input matInput placeholder="ClientCert Header" name="Client certificate" id="smlClientHeader_id"
[formControl]="domainForm.controls['smlClientKeyAlias']" maxlength="255" >
[formControl]="domainForm.controls['smlClientCertHeader']" maxlength="255" >
</mat-form-field>
<mat-form-field style="width:100%">
<input matInput placeholder="ClientCert Alias" name="Client certificate" id="smlClientKeyAlias_id"
......
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {UserRo} from "../../user/user-ro.model";
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {DomainRo} from "../domain-ro.model";
import {AlertService} from "../../alert/alert.service";
import {UserDetailsDialogComponent} from "../../user/user-details-dialog/user-details-dialog.component";
import {CertificateService} from "../../user/certificate.service";
import {UserService} from "../../user/user.service";
import {SearchTableEntityStatus} from "../../common/search-table/search-table-entity-status.model";
import {GlobalLookups} from "../../common/global-lookups";
@Component({
selector: 'domain-details-dialog',
......@@ -26,14 +23,23 @@ export class DomainDetailsDialogComponent {
domainForm: FormGroup;
domain;
notInList(list: string[], exception: string) {
return (c: AbstractControl): { [key: string]: any } => {
if (c.value && c.value !== exception && list.includes(c.value))
return {'notInList': {valid: false}};
constructor(private dialogRef: MatDialogRef<DomainDetailsDialogComponent>,
return null;
}
}
constructor(private lookups: GlobalLookups,
private dialogRef: MatDialogRef<DomainDetailsDialogComponent>,
private alertService: AlertService,
@Inject(MAT_DIALOG_DATA) public data: any,
private fb: FormBuilder) {
this.editMode = data.edit;
this.formTitle = this.editMode ? DomainDetailsDialogComponent.EDIT_MODE: DomainDetailsDialogComponent.NEW_MODE;
this.formTitle = this.editMode ? DomainDetailsDialogComponent.EDIT_MODE : DomainDetailsDialogComponent.NEW_MODE;
this.current = this.editMode
? {
...data.row,
......@@ -49,26 +55,33 @@ export class DomainDetailsDialogComponent {
this.domainForm = fb.group({
'domainCode': new FormControl({value:'', disabled: this.editMode}, [Validators.pattern(this.domainCodePattern)]),
'smlSubdomain': new FormControl({value: '', disabled: this.editMode}, [Validators.pattern(this.dnsDomainPattern)]),
'smlSmpId': new FormControl({value: ''}, [Validators.pattern(this.dnsDomainPattern)]),
'domainCode': new FormControl({value: '', disabled: this.editMode}, [Validators.pattern(this.domainCodePattern),
this.notInList(this.lookups.cachedDomainList.map(a => a.domainCode), this.current.domainCode)]),
'smlSubdomain': new FormControl({
value: '',
disabled: this.editMode
}, [Validators.pattern(this.dnsDomainPattern),
this.notInList(this.lookups.cachedDomainList.map(a => a.smlSubdomain), this.current.smlSubdomain)]),
'smlSmpId': new FormControl({value: ''}, [Validators.pattern(this.dnsDomainPattern),
this.notInList(this.lookups.cachedDomainList.map(a => a.smlSmpId), this.current.smlSmpId)]),
'smlClientCertHeader': new FormControl({value: ''}, null),
'smlClientKeyAlias': new FormControl({value: ''}, null),
'signatureKeyAlias': new FormControl({value:''}, null),
'signatureKeyAlias': new FormControl({value: ''}, null),
}, {
//validator: this.passwordConfirmationValidator
});
this.domainForm.controls['domainCode'].setValue(this.current.domainCode);
this.domainForm.controls['smlSubdomain'].setValue(this.current.smlSubdomain);
this.domainForm.controls['smlSmpId'].setValue(this.current.smlSmpId);
this.domainForm.controls['smlClientCertHeader'].setValue(this.current.smlClientCertHeader);
this.domainForm.controls['smlClientKeyAlias'].setValue(this.current.smlClientKeyAlias);
this.domainForm.controls['signatureKeyAlias'].setValue(this.current.signatureKeyAlias);
}
submitForm() {
this.checkValidity(this.domainForm)
this.dialogRef.close(true);
this.dialogRef.close(true);
}
checkValidity(g: FormGroup) {
......@@ -86,21 +99,27 @@ export class DomainDetailsDialogComponent {
public getCurrent(): DomainRo {
this.current.domainCode = this.domainForm.value['domainCode'];
this.current.smlSubdomain = this.domainForm.value['smlSubdomain'];
if (!this.editMode) {
this.current.domainCode = this.domainForm.value['domainCode'];
this.current.smlSubdomain = this.domainForm.value['smlSubdomain'];
}
this.current.smlSmpId = this.domainForm.value['smlSmpId'];
this.current.smlClientCertHeader = this.domainForm.value['smlClientCertHeader'];
this.current.smlClientKeyAlias = this.domainForm.value['smlClientKeyAlias'];
this.current.signatureKeyAlias = this.domainForm.value['signatureKeyAlias'];
return this.current;
}
updateDomainCode(event) {
this.current.domainCode = event.target.value;
}
updateSmlDomain(event) {
this.current.smlSubdomain = event.target.value;
}
updateSmlSmpId(event) {
this.current.smlSmpId = event.target.value;
}
......
import {Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {ColumnPicker} from '../common/column-picker/column-picker.model';
import {MatDialog, MatDialogRef} from '@angular/material';
import {MatDialog} from '@angular/material';
import {AlertService} from '../alert/alert.service';
import {DomainController} from './domain-controller';
import {HttpClient} from '@angular/common/http';
import {SmpConstants} from "../smp.constants";
import {GlobalLookups} from "../common/global-lookups";
@Component({
moduleId: module.id,
......@@ -24,11 +25,11 @@ export class DomainComponent implements OnInit {
filter: any = {};
constructor(protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog) {
constructor(protected lookups: GlobalLookups, protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog) {
}
ngOnInit() {
this.domainController = new DomainController(this.dialog);
this.domainController = new DomainController(this.lookups, this.dialog);
this.columnPicker.allColumns = [
{
......
<h2 mat-dialog-title>{{formTitle}}</h2>
<mat-dialog-content style="height:620px;width:1200px">
<mat-dialog-content style="height:600px;width:1200px">
<div fxLayout="row">
<div fxLayout="column">
<mat-card fxFlex="200px">
......@@ -9,8 +9,7 @@
<div class="panel">
<mat-form-field style="width:100%">
<input matInput placeholder="Participant identifier" name="participantIdentifier"
value="{{current.participantIdentifier}}" id="participantIdentifier_id"
(blur)="updateParticipantIdentifier($event)"
id="participantIdentifier_id"
[formControl]="dialogForm.controls['participantIdentifier']" maxlength="255" required>
<div
*ngIf="(!editMode && dialogForm.controls['participantIdentifier'].touched || editMode) && dialogForm.controls['participantIdentifier'].hasError('required')"
......@@ -21,8 +20,8 @@
<mat-form-field style="width:100%">
<input matInput placeholder="Participant scheme" name="participantScheme"
value="{{current.participantScheme}}" id="participantScheme_id"
(blur)="updateParticipantScheme($event)" [formControl]="dialogForm.controls['participantScheme']"
id="participantScheme_id"
[formControl]="dialogForm.controls['participantScheme']"
maxlength="255" required>
<div
*ngIf="(!editMode && dialogForm.controls['participantScheme'].touched || editMode) && dialogForm.controls['participantScheme'].hasError('required')"
......@@ -34,22 +33,27 @@
</mat-card-content>
</mat-card>
<mat-card>
<!-- mat-card-title>Owners/Domains</mat-card-title -->
<mat-card-content>
<mat-accordion>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>Owners</mat-panel-title>
<mat-panel-title>Owners*
</mat-panel-title>
<mat-panel-description>
Selected user count: {{usersSelected.selectedOptions.selected.length}}
<div>
Selected user count: {{usersSelected.selectedOptions?.selected.length}}
<div
*ngIf="(!editMode && dialogForm.controls['users'].touched || editMode) && dialogForm.controls['users'].hasError('minSelectedListCount')"
style="color:red; font-size: 70%">
At least one user (owner) must be selected!
</div>
</div>
</mat-panel-description>
</mat-expansion-panel-header>
<mat-selection-list #usersSelected [compareWith]="compareTableItemById"
(selectionChange)="userListChanged(usersSelected.selectedOptions.selected,$event)"
[formControl]="formControlUsers"
[formControl]="dialogForm.controls['users']"
style="height: 200px; overflow-y: scroll; overflow-x: auto;">
<mat-list-option *ngFor="let user of userlist" [value]='user'>
<mat-list-option *ngFor="let user of lookups?.cachedUserList" [value]='user'>
{{user.id}} - {{user.username?user.username:user.id}}
</mat-list-option>
</mat-selection-list>
......@@ -57,39 +61,104 @@
<mat-expansion-panel >
<mat-expansion-panel-header>
<mat-panel-title>Domains</mat-panel-title>
<mat-panel-title>Domains*</mat-panel-title>
<mat-panel-description>
Selected domain count: {{domainSelected.selectedOptions.selected.length}}
<div>
Selected domain count: {{domainSelector.selectedOptions?.selected.length}}
<div
*ngIf="(!editMode && dialogForm.controls['serviceGroupDomains'].touched || editMode) && dialogForm.controls['serviceGroupDomains'].hasError('minSelectedListCount')"
style="color:red; font-size: 70%">
At least one domain must be selected!
</div>
</div>
</mat-panel-description>
</mat-expansion-panel-header>
<mat-selection-list #domainSelected [compareWith]="compareTableItemById"
[formControl]="formControlDomain"
<mat-selection-list #domainSelector [compareWith]="compareDomain"
[formControl]="dialogForm.controls['serviceGroupDomains']"
(selectionChange)="onDomainSelectionChanged($event)"
style="height: 200px; overflow-y: scroll; overflow-x: auto;">
<mat-list-option *ngFor="let domain of domainList" [value]='domain'>
<mat-list-option *ngFor="let domain of lookups.cachedDomainList" [value]='domain'>
{{domain.domainCode}} ({{domain.smlSubdomain}})
</mat-list-option>
</mat-selection-list>
</mat-expansion-panel>
</mat-accordion>
<div
*ngIf="(!editMode && dialogForm.controls['users'].touched || editMode) && dialogForm.controls['users'].hasError('minSelectedListCount')"
style="color:red; font-size: 70%">
At least one user (owner) must be selected!
</div>
</mat-card-content>
</mat-card>
</div>
<mat-card fxFlex="60">
<mat-card-title>Extension</mat-card-title>
<mat-card-content>
<p>
<mat-card-title>Extension
<div style="font-size:70%">
Extension is automatically wrapped to root element to form vaild XML! No ExtensionWrapper element is needed.
</p>
<!--mat-form-field>
< textarea id="extensionTextArea" resizeable="false" placeholder="Extension" name="extension"></textarea>
</div>
</mat-card-title>
<mat-card-content >
<mat-toolbar>
<mat-toolbar-row>
<button mat-raised-button color="primary"
matTooltip="Clear the extension content."
matTooltipPosition="below"
(click)="onExtensionDelete()" >
<mat-icon>clear</mat-icon>
<span>Clear</span>
</button>
<button mat-raised-button color="primary"
matTooltip="Opens wizard for adding new Extension. New extension is appended to existing extensions."
matTooltipPosition="below"
(click)="onStartWizardDialog()">
<mat-icon>add_box</mat-icon>
<span>Extension wizard</span>
</button>
<button mat-raised-button color="primary"
atTooltip="Validate extension by XSD schema."
matTooltipPosition="below"
(click)="onExtensionValidate()">
<mat-icon>warning</mat-icon>
<span>Validate</span>
</button>
<!-- add and test this fuction on backend
button mat-raised-button color="primary"
atTooltip="Pritty print extension!"
matTooltipPosition="below"
(click)="onPrettyPrintExtension()">
<mat-icon>warning</mat-icon>
<span>format XML</span>
</button -->
</mat-toolbar-row>
</mat-toolbar>
<div style="display: block;" style="border:1px; solid: #999999;margin:5px 0; padding:3px;">
<div class="textwrapper">
<textarea matInput style="width:100%;border: #03A9F4 1px solid" cols="2" rows="30"
resizeable="false"
id="extensionTextArea"
placeholder="Extension" name="extension"
[formControl]="dialogForm.controls['extension']"
></textarea>
</div>
<div
*ngIf="extensionValidationMessage"
[style.color]="isExtensionValid?'green':'red'">
{{extensionValidationMessage}}
</div>
</div>
<!-- mat-form-field>
<div>
<textarea style="width:100% !important;height: 400px !important; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;"
matInput id="extensionTextArea"
placeholder="Extension" name="extension"
[formControl]="dialogForm.controls['extension']"
></textarea>
</div>
</mat-form-field -->
</mat-card-content>
</mat-card>
......
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {ChangeDetectorRef, Component, Inject, OnInit, ViewChild} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {Observable} from "rxjs/internal/Observable";
import {SearchTableResult} from "../../common/search-table/search-table-result.model";
import {HttpClient} from "@angular/common/http";
import {SmpConstants} from "../../smp.constants";
import {UserRo} from "../../user/user-ro.model";
import {AlertService} from "../../alert/alert.service";
import {DomainDetailsDialogComponent} from "../../domain/domain-details-dialog/domain-details-dialog.component";
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {SearchTableEntityStatus} from "../../common/search-table/search-table-entity-status.model";
import {DomainRo} from "../../domain/domain-ro.model";
import {ServiceGroupEditRo} from "../service-group-edit-ro.model";
import {ServiceMetadataEditRo} from "../service-metadata-edit-ro.model";
import {GlobalLookups} from "../../common/global-lookups";
import {ServiceGroupExtensionWizardDialogComponent} from "../service-group-extension-wizard-dialog/service-group-extension-wizard-dialog.component";
import {ServiceGroupExtensionRo} from "./service-extension-edit-ro.model";
import {DomainRo} from "../../domain/domain-ro.model";
import {ServiceGroupDomainEditRo} from "../service-group-domain-edit-ro.model";
import {ConfirmationDialogComponent} from "../../common/confirmation-dialog/confirmation-dialog.component";
@Component({
selector: 'app-messagelog-details',
selector: 'service-group-details',
templateUrl: './service-group-details-dialog.component.html',
styleUrls: ['./service-group-details-dialog.component.css']
})
export class ServiceGroupDetailsDialogComponent {
export class ServiceGroupDetailsDialogComponent implements OnInit {
static readonly NEW_MODE = 'New ServiceGroup';
static readonly EDIT_MODE = 'ServiceGroup Edit';
@ViewChild('domainSelector') domainSelector: any;
userObserver: Observable< SearchTableResult> ;
domainObserver: Observable< SearchTableResult> ;
userlist: Array<UserRo> = [];
domainList: Array<DomainRo> = [];
editMode: boolean;
formTitle: string;
current: ServiceGroupEditRo & { confirmation?: string };
dialogForm: FormGroup;
dialogFormBuilder: FormBuilder;
formControlUsers: FormControl;
formControlDomain: FormControl;
/*
selectedDomain: DomainRo;
domainList: Array<any>;
*/
extensionObserver: Observable<ServiceGroupExtensionRo>;
extensionValidationMessage: String = null;
isExtensionValid: boolean = true;
serviceGroupDomain: ServiceGroupDomainEditRo[];
minSelectedListCount(min: number) {
return (c: AbstractControl): {[key: string]: any} => {
if (c.value.length >= min)
return (c: AbstractControl): { [key: string]: any } => {
if (c.value && c.value.length >= min)
return null;
return { 'minCountOwners': {valid: false }};
return {'minSelectedListCount': {valid: false}};
}
}
constructor(protected http: HttpClient,
constructor(public dialog: MatDialog,
protected http: HttpClient,
public dialogRef: MatDialogRef<ServiceGroupDetailsDialogComponent>,
private alertService: AlertService,
private lookups: GlobalLookups,
public lookups: GlobalLookups,
@Inject(MAT_DIALOG_DATA) public data: any,
private fb: FormBuilder) {
// init user list
this.userObserver = this.http.get<SearchTableResult>(SmpConstants.REST_USER);
this.userObserver.subscribe((users: SearchTableResult) => {
this.userlist = new Array(users.serviceEntities.length)
.map((v, index) => users.serviceEntities[index] as UserRo);
this.userlist = users.serviceEntities.map(serviceEntity => {
return {...<UserRo>serviceEntity}
});
this.updateUserData();
});
// domain service group
this.lookups.getDomainLookupObservable().subscribe((domains: SearchTableResult) => {
this.domainList = new Array(domains.serviceEntities.length)
.map((v, index) => domains.serviceEntities[index] as DomainRo);
this.domainList = domains.serviceEntities.map(serviceEntity => {
return {...<DomainRo>serviceEntity}
});
this.updateDomainData();
});
this.dialogFormBuilder = fb;
this.editMode = data.edit;
this.formTitle = this.editMode ? ServiceGroupDetailsDialogComponent.EDIT_MODE: ServiceGroupDetailsDialogComponent.NEW_MODE;
private dialogFormBuilder: FormBuilder,
private changeDetector: ChangeDetectorRef) {
this.editMode = this.data.edit;
this.formTitle = this.editMode ? ServiceGroupDetailsDialogComponent.EDIT_MODE : ServiceGroupDetailsDialogComponent.NEW_MODE;
this.current = this.editMode
? {
...data.row,
...this.data.row,
}
: {
id: null,
participantIdentifier: '',
participantScheme: '',
serviceMetadata:[],
users:[],
domainCode:'',
participantScheme: '',
serviceMetadata: [],
users: [],
serviceGroupDomains: [],
extension: '',
status: SearchTableEntityStatus.NEW,
};
// user is new when reopening the new item in edit mode!
// allow to change data but warn on error!
this.dialogForm = this.dialogFormBuilder.group({
'participantIdentifier': new FormControl({value: this.current.participantIdentifier, disabled: this.editMode}, this.editMode ? Validators.required : null),
'participantScheme': new FormControl({value: this.current.participantScheme, disabled: this.editMode}, this.editMode ? Validators.required : null),
'domainCode': new FormControl({value: this.current.domainCode},this.editMode ? Validators.required : null),
'participantIdentifier': new FormControl({
value: '',
disabled: this.current.status !== SearchTableEntityStatus.NEW
},
this.current.status !== SearchTableEntityStatus.NEW ? Validators.required : null),
'participantScheme': new FormControl({value: '', disabled: this.current.status !== SearchTableEntityStatus.NEW},
this.current.status !== SearchTableEntityStatus.NEW ? Validators.required : null),
'serviceGroupDomains': new FormControl({value: []}, [this.minSelectedListCount(1)]),
'users': new FormControl({value: []}, [this.minSelectedListCount(1)]),
'extension': new FormControl({value: []}, []),
});
});
// update values
this.dialogForm.controls['participantIdentifier'].setValue(this.current.participantIdentifier);
this.dialogForm.controls['participantScheme'].setValue(this.current.participantScheme);
this.dialogForm.controls['serviceGroupDomains'].setValue(this.current.serviceGroupDomains);
this.dialogForm.controls['users'].setValue(this.current.users)
this.dialogForm.controls['extension'].setValue(this.current.extension)
}
updateUserData(){
this.formControlUsers = new FormControl(this.current.users);
this.formControlUsers.setValidators( [ this.minSelectedListCount(1)]);
this.dialogForm.addControl("users",this.formControlUsers );
}
ngOnInit() {
// retrieve xml extension for this service group
if (this.current.status !== SearchTableEntityStatus.NEW && !this.current.extension) {
// init domains
this.extensionObserver = this.http.get<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION+'/' + this.current.id);
this.extensionObserver.subscribe((res: ServiceGroupExtensionRo) => {
this.dialogForm.get('extension').setValue(res.extension);
});
}
updateDomainData(){
this.formControlDomain = new FormControl(this.current.domains);
this.formControlDomain.setValidators( [ this.minSelectedListCount(1)]);
this.dialogForm.addControl("domains",this.formControlDomain );
// detect changes for updated values in mat-selection-list (check change detection operations)
// else the following error is thrown :xpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value:
// 'aria-selected: false'. Current value: 'aria-selected: true'
//
this.changeDetector.detectChanges()
}
......@@ -141,24 +135,145 @@ export class ServiceGroupDetailsDialogComponent {
}
updateParticipantIdentifier(event) {
this.current.participantIdentifier = event.target.value;
compareTableItemById(item1, item2): boolean {
return item1.id === item2.id;
}
updateParticipantScheme(event) {
this.current.participantScheme = event.target.value;
compareDomain(domain: DomainRo, serviceGroupDomain: ServiceGroupDomainEditRo): boolean {
return domain.id === serviceGroupDomain.domainId;
}
userListChanged(usersSelected, event){
this.current.users = [];
for(let usr of usersSelected) {
this.current.users.push(usr.value);
public getCurrent(): ServiceGroupEditRo {
// change this two properties only on new
if (this.current.status === SearchTableEntityStatus.NEW) {
this.current.participantIdentifier = this.dialogForm.value['participantIdentifier'];
this.current.participantScheme = this.dialogForm.value['participantScheme'];
} else {
this.current.extensionStatus = SearchTableEntityStatus.UPDATED;
}
this.current.users = this.dialogForm.value['users'];
this.current.extension = this.dialogForm.value['extension'];
let domainOptions = this.domainSelector.options._results;
domainOptions.forEach(opt => {
let domValue = opt.value;
let sgd = this.getServiceGroupDomain(domValue.domainCode);
// if contains and deselected - delete
if (sgd && !opt.selected) {
this.current.serviceMetadata.forEach(metadata=>{
if (metadata.domainCode === sgd.domainCode) {
metadata.status = SearchTableEntityStatus.REMOVED;
metadata.deleted = true;
}
});
var index = this.current.serviceGroupDomains.indexOf(sgd);
if (index !== -1) this.current.serviceGroupDomains.splice(index, 1);
// delete service group
} else if (!sgd && opt.selected) {
let newDomain: ServiceGroupDomainEditRo = {
id: null,
domainId: domValue.id,
domainCode: domValue.domainCode,
smlSubdomain: domValue.domainCode,
smlRegistered: false,
serviceMetadataCount: 0,
status: SearchTableEntityStatus.NEW,
};
this.current.serviceGroupDomains.push(newDomain);
}
});
return this.current;
}
compareTableItemById(item1, item2): boolean{
return item1.id=== item2.id;
onExtensionDelete() {
this.dialogForm.controls['extension'].setValue("");
}
onStartWizardDialog() {
const formRef: MatDialogRef<any> = this.dialog.open(ServiceGroupExtensionWizardDialogComponent);
formRef.afterClosed().subscribe(result => {
if (result) {
let existingXML = this.dialogForm.controls['extension'].value;
let val = (existingXML ? existingXML + '\n' : '') + formRef.componentInstance.getExtensionXML();
this.dialogForm.controls['extension'].setValue(val);
}
});
}
onExtensionValidate() {
let existingXML = this.dialogForm.controls['extension'].value;
let request: ServiceGroupExtensionRo = {
serviceGroupId: this.current.id,
extension: existingXML,
}
//
let validationObservable = this.http.post<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION_VALIDATE, request);
validationObservable.subscribe((res: ServiceGroupExtensionRo) => {
if (res.errorMessage) {
this.extensionValidationMessage = res.errorMessage;
this.isExtensionValid = false;
} else {
this.extensionValidationMessage = "Extension is valid!";
this.isExtensionValid = true;
}
});
}
onPrettyPrintExtension() {
let existingXML = this.dialogForm.controls['extension'].value;
let request: ServiceGroupExtensionRo = {
serviceGroupId: this.current.id,
extension: existingXML,
}
let validationObservable = this.http.post<ServiceGroupExtensionRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION_FORMAT, request);
validationObservable.subscribe((res: ServiceGroupExtensionRo) => {
if (res.errorMessage) {
this.extensionValidationMessage = res.errorMessage;
this.isExtensionValid = false;
} else {
this.dialogForm.get('extension').setValue(res.extension);
this.isExtensionValid = true;
}
});
}
isSelected(id): boolean {
return !!this.current.users.find(user => user.id===id);
onDomainSelectionChanged(event) {
// if deselected warn serviceMetadata will be deleted
let domainCode = event.option.value.domainCode;
if (!event.option.selected) {
this.dialog.open(ConfirmationDialogComponent, {
data: {
title: "Registred serviceMetadata on domain!",
description: "Unregistration of domain will also delete it's serviceMetadata. Do you want to continue?"
}
}).afterClosed().subscribe(result => {
if (!result) {
event.option.selected = true;
}
})
}
}
public getServiceMetadataCountOnDomain(domainCode: String) {
return this.current.serviceMetadata.filter(smd => {
return smd.domainCode === domainCode
}).length;
}
public getServiceGroupDomain(domainCode: String) {
return this.current.serviceGroupDomains?
this.current.serviceGroupDomains.find(smd => {
return smd.domainCode === domainCode
}):null;
}
}
import { ServiceMetadataEditRo } from './service-metadata-edit-ro.model';
import {SearchTableEntity} from "../common/search-table/search-table-entity.model";
import {UserRo} from "../user/user-ro.model";
import {DomainRo} from "../domain/domain-ro.model";
export interface ServiceGroupEditRo extends SearchTableEntity {
export interface ServiceGroupDomainEditRo extends SearchTableEntity {
id: number;
participantIdentifier: string;
participantScheme: string;
serviceMetadata: Array<ServiceMetadataEditRo>;
serviceGroupDomains: Array<ServiceGroupDomainRo>;
users: Array<UserRo>;
extension?: string;
domainId: number;
domainCode: string;
smlSubdomain: string;
smlRegistered: boolean;
serviceMetadataCount?: number;
}
......@@ -4,7 +4,6 @@ import {ServiceGroupDetailsDialogComponent} from './service-group-details-dialog
import {ServiceGroupEditRo} from './service-group-edit-ro.model';
import {SearchTableEntityStatus} from '../common/search-table/search-table-entity-status.model';
import {ServiceMetadataEditRo} from "./service-metadata-edit-ro.model";
import {DomainDetailsDialogComponent} from "../domain/domain-details-dialog/domain-details-dialog.component";
import {ServiceGroupMetadataDialogComponent} from "./service-group-metadata-dialog/service-group-metadata-dialog.component";
export class ServiceGroupEditController implements SearchTableController {
......@@ -49,11 +48,10 @@ export class ServiceGroupEditController implements SearchTableController {
index: null,
participantIdentifier: '',
participantScheme: '',
domainCode: '',
smlSubdomain: '',
serviceMetadata: [],
users: [],
domains: [],
serviceGroupDomains: [],
extensionStatus: SearchTableEntityStatus.NEW,
status: SearchTableEntityStatus.NEW
};
}
......@@ -65,12 +63,12 @@ export class ServiceGroupEditController implements SearchTableController {
documentIdentifierScheme: '',
smlSubdomain: '',
domainCode: '',
processSchema: '',
processIdentifier: '',
endpointUrl: '',
endpointCertificate: '',
status: SearchTableEntityStatus.NEW
domainId:null,
status: SearchTableEntityStatus.NEW,
xmlContentStatus: SearchTableEntityStatus.NEW,
};
}
public dataSaved() {}
}
import { ServiceMetadataEditRo } from './service-metadata-edit-ro.model';
import {ServiceMetadataEditRo} from './service-metadata-edit-ro.model';
import {SearchTableEntity} from "../common/search-table/search-table-entity.model";
import {UserRo} from "../user/user-ro.model";
import {DomainRo} from "../domain/domain-ro.model";
import {ServiceGroupDomainEditRo} from "./service-group-domain-edit-ro.model";
import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model";
export interface ServiceGroupEditRo extends SearchTableEntity {
id: number;
participantIdentifier: string;
participantScheme: string;
domainCode:'',
smlSubdomain:'',
serviceMetadata: Array<ServiceMetadataEditRo>;
domains: Array<DomainRo>;
serviceGroupDomains: Array<ServiceGroupDomainEditRo>;
users: Array<UserRo>;
extension?: string;
extensionStatus: SearchTableEntityStatus;
}
......@@ -27,19 +27,19 @@
<ng-template #searchPanel>
<mat-form-field>
<input matInput placeholder="Participant Id" name="messageId" [(ngModel)]="filter.messageId"
#messageId="ngModel" id="messageid_id">
<input matInput placeholder="Participant Identifier" name="ParticipantIdentifier"
[(ngModel)]="filter.participantIdentifier"
#messageId="ngModel" id="participantIdentifier">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Participant schema" name="patricipantSchema" [(ngModel)]="filter.messageId"
#messageId="ngModel" id="participanschema_id">
<input matInput placeholder="Participant scheme" name="patricipantScheme" [(ngModel)]="filter.participantScheme"
#messageId="ngModel" id="participantScheme">
</mat-form-field>
<mat-select placeholder="Domain (sml subdomain)" [(ngModel)]="filter.domain" name="domain"
id="domain_id">
<mat-option [value]="''">
</mat-option>
<mat-option *ngFor="let domain of domainlist" [value]="domain.domainCode">
<mat-option *ngFor="let domain of lookups.cachedDomainList" [value]="domain.domainCode">
{{domain.domainCode}} ({{domain.smlSubdomain}})
</mat-option>
</mat-select>
......@@ -70,12 +70,16 @@
[footerHeight]='50'
[rowHeight]='"auto"'
[rowClass]="getRowClass">
<ngx-datatable-column prop="domainCode" name="Domain" maxWidth="250" ></ngx-datatable-column>
<ngx-datatable-column [cellTemplate]="rowDomain" name="Domain" maxWidth="250" ></ngx-datatable-column>
<ngx-datatable-column prop="documentIdentifierScheme" name="Document identifier scheme" maxWidth="350" ></ngx-datatable-column>
<ngx-datatable-column prop="documentIdentifier" name="Document identifier" maxWidth="250" ></ngx-datatable-column>
<ngx-datatable-column [cellTemplate]="rowMetadataSMPUrlLinkAction" name="URL" maxWidth="250" ></ngx-datatable-column>
<ngx-datatable-column [cellTemplate]="rowMetadataActions" name="Actions" maxWidth="150" ></ngx-datatable-column>
<ng-template #rowDomain let-rowSmd="row" ngx-datatable-cell-template>
{{rowSmd.domainCode}} ({{rowSmd.smlSubdomain}})
</ng-template>
<ng-template #rowMetadataSMPUrlLinkAction let-rowSmd="row" ngx-datatable-cell-template>
<a target="_blank"
href="{{contextPath}}{{row.participantScheme}}::{{row.participantIdentifier}}/services/{{rowSmd.documentIdentifierScheme}}::{{rowSmd.documentIdentifier}}" >Open URL</a>
......@@ -85,7 +89,7 @@
<ng-template #rowMetadataActions let-rowSmd="row" ngx-datatable-cell-template>
<div>
<button mat-icon-button color="primary" [disabled]="rowSmd.deleted || loading"
(click)="onEditMetadataRow(rowSmd)" tooltip="Edit">
(click)="onEditMetadataRow(row, rowSmd)" tooltip="Edit">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="primary" [disabled]="rowSmd.deleted || loading"
......
import {Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {ChangeDetectorRef, Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {ColumnPicker} from '../common/column-picker/column-picker.model';
import {MatDialog, MatDialogRef} from '@angular/material';
import {AlertService} from '../alert/alert.service';
import {ServiceGroupEditController} from './service-group-edit-controller';
import {HttpClient} from '@angular/common/http';
import {ServiceGroupDetailsDialogComponent} from "./service-group-details-dialog/service-group-details-dialog.component";
import {SmpConstants} from "../smp.constants";
import {Observable} from "rxjs/internal/Observable";
import {UserRo} from "../user/user-ro.model";
import {SearchTableResult} from "../common/search-table/search-table-result.model";
import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model";
import {SearchTableComponent} from "../common/search-table/search-table.component";
import {ServiceMetadataEditRo} from "./service-metadata-edit-ro.model";
import {ServiceGroupEditRo} from "./service-group-edit-ro.model";
import {GlobalLookups} from "../common/global-lookups";
import {DomainRo} from "../domain/domain-ro.model";
@Component({
moduleId: module.id,
......@@ -33,31 +26,12 @@ export class ServiceGroupEditComponent implements OnInit {
filter: any = {};
baseUrl: string = SmpConstants.REST_EDIT;
userObserver: Observable<SearchTableResult>;
domainObserver: Observable<SearchTableResult>;
userlist: Array<UserRo> = [];
domainlist: Array<any>;
constructor(protected lookups: GlobalLookups,
protected http: HttpClient,
protected alertService: AlertService,
public dialog: MatDialog,
private changeDetector: ChangeDetectorRef) {
constructor(protected lookups: GlobalLookups, protected http: HttpClient, protected alertService: AlertService, public dialog: MatDialog) {
this.userObserver = this.http.get<SearchTableResult>(SmpConstants.REST_USER);
this.userObserver.subscribe((users: SearchTableResult) => {
this.userlist = new Array(users.serviceEntities.length)
.map((v, index) => users.serviceEntities[index] as UserRo);
this.userlist = users.serviceEntities.map(serviceEntity => {
return {...<UserRo>serviceEntity}
});
});
this.lookups.getDomainLookupObservable().subscribe((domains: SearchTableResult) => {
this.domainlist = new Array(domains.serviceEntities.length)
.map((v, index) => domains.serviceEntities[index] as DomainRo);
this.domainlist = domains.serviceEntities.map(serviceEntity => {
return {...<DomainRo>serviceEntity}
});
});
}
ngOnInit() {
......@@ -116,7 +90,7 @@ export class ServiceGroupEditComponent implements OnInit {
let rowNumber = this.searchTable.rows.indexOf(row);
const formRef: MatDialogRef<any> = this.serviceGroupEditController.newMetadataDialog({
data: {edit: true, serviceGroup: row, metadata: null}
data: {edit: false, serviceGroup: row, metadata: this.serviceGroupEditController.newServiceMetadataRow()}
});
formRef.afterClosed().subscribe(result => {
if (result) {
......@@ -124,21 +98,9 @@ export class ServiceGroupEditComponent implements OnInit {
? SearchTableEntityStatus.UPDATED
: row.status;
let data = this.serviceGroupEditController.newServiceMetadataRow();
data.documentIdentifier = "aaaaaaaaa";
data.documentIdentifierScheme = "aaaaaaaaa";
let data = formRef.componentInstance.getCurrent();
row.serviceMetadata.push(data);
this.searchTable.updateTableRow(rowNumber, row, status);
//this.searchTable.rows[rowNumber] = {...row, status};
//this.searchTable.rows = [...this.searchTable.rows];
/*
const status = row.status === SearchTableEntityStatus.PERSISTED
? SearchTableEntityStatus.UPDATED
: row.status;
this.rows[rowNumber] = {...formRef.componentInstance.current, status};
this.rows = [...this.rows];*/
}
});
......@@ -152,7 +114,38 @@ export class ServiceGroupEditComponent implements OnInit {
};
}
onEditMetadataRow(metaDataRow: any) {
onEditMetadataRow(serviceGroupRow: any,metaDataRow: any) {
let metadataRowNumber = serviceGroupRow.serviceMetadata.indexOf(metaDataRow);
const formRef: MatDialogRef<any> = this.serviceGroupEditController.newMetadataDialog({
data: {edit: true, serviceGroup: serviceGroupRow, metadata: metaDataRow}
});
formRef.afterClosed().subscribe(result => {
if (result) {
let statusMetadata =metaDataRow.status === SearchTableEntityStatus.PERSISTED
? SearchTableEntityStatus.UPDATED
: metaDataRow;
metaDataRow.status = statusMetadata;
metaDataRow = {...formRef.componentInstance.getCurrent()};
serviceGroupRow.serviceMetadata [metadataRowNumber] = {...metaDataRow };
// change reference to fire table update
serviceGroupRow.serviceMetadata = [...serviceGroupRow.serviceMetadata]
// set row as updated
const status = serviceGroupRow.status === SearchTableEntityStatus.PERSISTED
? SearchTableEntityStatus.UPDATED
: serviceGroupRow.status;
serviceGroupRow.status = status;
this.changeDetector.detectChanges();
}
});
//
}
......
import {ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
import {Observable} from "rxjs/internal/Observable";
import {SearchTableResult} from "../common/search-table/search-table-result.model";
import {HttpClient} from "@angular/common/http";
import {SmpConstants} from "../smp.constants";
import {UserRo} from "../user/user-ro.model";
import {AlertService} from "../alert/alert.service";
import {DomainDetailsDialogComponent} from "../domain/domain-details-dialog/domain-details-dialog.component";
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model";
import {DomainRo} from "../domain/domain-ro.model";
import {ServiceGroupEditRo} from "./service-group-edit-ro.model";
import {ServiceMetadataEditRo} from "./service-metadata-edit-ro.model";
import {GlobalLookups} from "../common/global-lookups";
import {Component} from '@angular/core';
import {MatDialogRef} from '@angular/material';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
@Component({
selector: 'app-messagelog-details',
templateUrl: './service-group-metadata-wizard-dialog/service-group-extension-wizard-dialog.component.html',
styleUrls: ['./service-group-metadata-wizard-dialog/service-group-extension-wizard-dialog.component.css']
selector: 'service-group-metadata-wizard',
templateUrl: './service-group-extension-wizard-dialog.component.html',
styleUrls: ['./service-group-extension-wizard-dialog.component.css']
})
export class ServiceGroupExtensionWizardDialogComponent {
dialogForm: FormGroup;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment