dataset editor

This commit is contained in:
annampak 2017-12-18 16:28:08 +02:00
parent 11fa25da40
commit a793e0f365
5 changed files with 343 additions and 3 deletions

View File

@ -0,0 +1,35 @@
.full-width {
width: 100%;
}
.input-table {
table-layout: fixed;
}
.table-card .mat-grid-tile {
background: rgba(0, 0, 0, 0.32);
}
.project-editor {
mat-form-field {
width: 100%;
padding: 3px;
}
.mat-card {
margin: 16px 0;
}
p {
margin: 16px;
}
.left-button {
float: left;
}
.description-area {
height: 100px;
}
}

View File

@ -0,0 +1,97 @@
<div class="project-editor">
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<mat-card>
<mat-card-title *ngIf="isNew">{{'DMP-EDITOR.TITLE.NEW' | translate}}</mat-card-title>
<mat-card-title *ngIf="!isNew">{{'DMP-EDITOR.TITLE.EDIT' | translate}} {{project.label}}</mat-card-title>
<mat-card-content>
<mat-form-field>
<input matInput placeholder="{{'DMP-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" formControlName="label" required>
<mat-error *ngIf="formGroup.get('label').errors?.backendError">{{baseErrorModel.label}}</mat-error>
<mat-error *ngIf="formGroup.get('label').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- <mat-form-field>
<input matInput placeholder="{{'DMP-EDITOR.FIELDS.ABBREVIATION' | translate}}" type="text" name="abbreviation" formControlName="abbreviation"
required>
<mat-error *ngIf="formGroup.get('abbreviation').errors?.backendError">{{baseErrorModel.abbreviation}}</mat-error>
<mat-error *ngIf="formGroup.get('abbreviation').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="{{'DMP-EDITOR.FIELDS.URI' | translate}}" type="text" name="uri" formControlName="uri" required>
<mat-error *ngIf="formGroup.get('uri').errors?.backendError">{{baseErrorModel.uri}}</mat-error>
<mat-error *ngIf="formGroup.get('uri').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> -->
<!-- <table class="input-table full-width">
<tr>
<td>
<mat-form-field>
<input matInput (focus)="startDate.open()" (click)="startDate.open()" placeholder="{{'DMP-EDITOR.FIELDS.START' | translate}}"
class="table-input" [matDatepicker]="startDate" formControlName="startDate" required>
<mat-datepicker-toggle matSuffix [for]="startDate"></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
<mat-error *ngIf="formGroup.get('startDate').errors?.backendError">{{baseErrorModel.startDate}}</mat-error>
<mat-error *ngIf="formGroup.get('startDate').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</td>
<td>
<mat-form-field>
<input matInput (focus)="endDate.open()" (click)="endDate.open()" placeholder="{{'DMP-EDITOR.FIELDS.END' | translate}}"
class="table-input" [matDatepicker]="endDate" formControlName="endDate" required>
<mat-datepicker-toggle matSuffix [for]="endDate"></mat-datepicker-toggle>
<mat-datepicker #endDate></mat-datepicker>
<mat-error *ngIf="formGroup.get('endDate').errors?.backendError">{{baseErrorModel.endDate}}</mat-error>
<mat-error *ngIf="formGroup.get('endDate').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</td>
</tr>
</table> -->
<mat-form-field class="full-width">
<textarea matInput class="description-area" placeholder="{{'DMP-EDITOR.FIELDS.DESCRIPTION' | translate}}" formControlName="description"
required></textarea>
<mat-error *ngIf="formGroup.get('description').errors?.backendError">{{errorModel.description}}</mat-error>
<mat-error *ngIf="formGroup.get('description').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<td-chips color="accent" [items]="filteredOrganisations" formControlName="organisations" placeholder="{{'DMP-EDITOR.FIELDS.ORGANISATIONS' | translate}}"
(inputChange)="filterOrganisations($event)" requireMatch>
<ng-template td-chip let-chip="chip">
<div class="tc-grey-100 bgc-teal-700" td-chip-avatar>{{chip.name.substring(0, 1).toUpperCase()}}</div>
{{chip.name}}
</ng-template>
<ng-template td-autocomplete-option let-option="option">
<div layout="row" layout-align="start center">
{{option.name}}
</div>
</ng-template>
<mat-progress-bar [style.height.px]="2" *ngIf="filteringOrganisationsAsync" mode="indeterminate"></mat-progress-bar>
</td-chips>
<td-chips color="accent" [items]="filteredResearchers" formControlName="researchers" placeholder="{{'DMP-EDITOR.FIELDS.RESEARCHERS' | translate}}"
(inputChange)="filterResearchers($event)" requireMatch>
<ng-template td-chip let-chip="chip">
<div class="tc-grey-100 bgc-teal-700" td-chip-avatar>{{chip.name.substring(0, 1).toUpperCase()}}</div>
{{chip.name}}
</ng-template>
<ng-template td-autocomplete-option let-option="option">
<div layout="row" layout-align="start center">
{{option.name}}
</div>
</ng-template>
<mat-progress-bar [style.height.px]="2" *ngIf="filteringResearchersAsync" mode="indeterminate"></mat-progress-bar>
</td-chips>
<div layout="row" class="full-width text-right" align="end">
<button mat-raised-button color="primary" (click)="cancel()" type="button">{{'DMP-EDITOR.ACTIONS.CANCEL' | translate}}</button>
<button mat-raised-button color="primary" type="submit">{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}</button>
<button *ngIf="!isNew" mat-raised-button color="primary" type="submit" (click)="delete()">{{'DMP-EDITOR.ACTIONS.DELETE' | translate}}</button>
</div>
</mat-card-content>
</mat-card>
</form>
<div *ngIf="formGroup"> {{ formGroup.value | json }}</div>
</div>

View File

@ -0,0 +1,144 @@
import { Component, ViewChild, OnInit, AfterViewInit, ViewEncapsulation } from "@angular/core";
import { MatPaginator, MatSort, MatSnackBar } from "@angular/material";
import { Router, ActivatedRoute, Params } from "@angular/router";
import { TranslateService } from "@ngx-translate/core";
import { DataSource } from "@angular/cdk/table";
import { Observable } from "rxjs/Observable";
import { JsonSerializer } from "../../utilities/JsonSerializer";
import { FormGroup } from "@angular/forms";
import { SnackBarNotificationComponent } from "../../shared/components/notificaiton/snack-bar-notification.component";
import { BaseErrorModel } from "../../models/error/BaseErrorModel";
import { DatasetService } from "../../services/dataset/dataset.service";
import { DatasetModel } from "../../models/datasets/DatasetModel";
import { ServerService } from "../../services/server.service";
import { ExternalSourcesService } from "../../services/external-sources/external-sources.service";
import { ExternalSourcesItemModel } from "../../models/external-sources/ExternalSourcesItemModel";
@Component({
selector: 'app-dataset-editor-component',
templateUrl: 'dataset-editor.component.html',
styleUrls: ['./dataset-editor.component.scss'],
providers: [DatasetService, ExternalSourcesService],
encapsulation: ViewEncapsulation.None
})
export class DatasetEditorComponent implements AfterViewInit {
isNew = true;
dataManagementPlan: DatasetModel;
formGroup: FormGroup = null;
filteringOrganisationsAsync: boolean = false;
filteringResearchersAsync: boolean = false;
filteredOrganisations: ExternalSourcesItemModel[];
filteredResearchers: ExternalSourcesItemModel[];
constructor(
private datasetService: DatasetService,
private externalSourcesService: ExternalSourcesService,
private route: ActivatedRoute,
public snackBar: MatSnackBar,
public router: Router,
public language: TranslateService,
) {
}
ngAfterViewInit() {
this.route.params.subscribe((params: Params) => {
const itemId = params['id'];
if (itemId != null) {
this.isNew = false;
this.datasetService.getSingle(itemId).map(data => data as DatasetModel)
.subscribe(data => {
this.dataManagementPlan = new JsonSerializer<DatasetModel>().fromJSONObject(data, DatasetModel);
this.formGroup = this.dataManagementPlan.buildForm();
});
} else {
this.dataManagementPlan = new DatasetModel();
setTimeout(() => {
this.formGroup = this.dataManagementPlan.buildForm();
});
}
});
}
formSubmit(): void {
//this.touchAllFormFields(this.formGroup);
if (!this.isFormValid()) { return; }
//this.onSubmit();
}
public isFormValid() {
return this.formGroup.valid;
}
// onSubmit(): void {
// this.dataManagementPlanService.createDataManagementPlan(this.formGroup.value).subscribe(
// complete => this.onCallbackSuccess(),
// error => this.onCallbackError(error)
// );
// }
onCallbackSuccess(): void {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dataManagementPlans']);
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
//this.validateAllFormFields(this.formGroup);
}
public setErrorModel(errorModel: BaseErrorModel) {
Object.keys(errorModel).forEach(item => {
(<any>this.dataManagementPlan.errorModel)[item] = (<any>errorModel)[item];
})
}
public cancel(): void {
this.router.navigate(['/dataManagementPlans']);
}
filterOrganisations(value: string): void {
this.filteredOrganisations = undefined;
if (value) {
this.filteringOrganisationsAsync = true;
this.externalSourcesService.searchDMPOrganizations(value).subscribe(items => {
this.filteredOrganisations = items;
this.filteringOrganisationsAsync = false;
// this.filteredOrganisations = items.filter((filteredObj: any) => {
// return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true;
// });
});
}
}
filterResearchers(value: string): void {
this.filteredResearchers = undefined;
if (value) {
this.filteringResearchersAsync = true;
this.externalSourcesService.searchDMPResearchers(value).subscribe(items => {
this.filteredResearchers = items;
this.filteringResearchersAsync = false;
// this.filteredOrganisations = items.filter((filteredObj: any) => {
// return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true;
// });
});
}
}
}

View File

@ -0,0 +1,63 @@
import { Serializable } from "../Serializable";
import { ValidationContext } from "../../utilities/validators/ValidationContext";
import { FormGroup, FormBuilder, FormControl, Validators } from "@angular/forms";
import { BackendErrorValidator } from "../../utilities/validators/BackendErrorValidator";
import { BaseErrorModel } from "../error/BaseErrorModel";
import { AutoCompleteItem } from "../../shared/components/autocomplete/AutoCompleteItem";
import { ExternalSourcesItemModel } from "../external-sources/ExternalSourcesItemModel";
export class DatasetModel implements Serializable<DatasetModel> {
public id: String;
public label: String;
public profile: String;
public uri: String;
public status: String;
public description: String;
public services: ExternalSourcesItemModel[] = [];
public registries: ExternalSourcesItemModel[] = [];
public dataRepositories: ExternalSourcesItemModel[] = [];
public errorModel: BaseErrorModel = new BaseErrorModel();
fromJSONObject(item: any): DatasetModel {
this.id = item.id;
this.label = item.label;
this.profile = item.profile;
this.uri = item.uri;
this.status = item.status;
this.description = item.description;
return this;
}
buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup {
if (context == null) { context = this.createValidationContext(); }
const formGroup = new FormBuilder().group({
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
profile: [{ value: this.profile, disabled: disabled }, context.getValidation('profile').validators],
uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators],
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
services: [{ value: this.services, disabled: disabled }, context.getValidation('services').validators],
registries: [{ value: this.registries, disabled: disabled }, context.getValidation('registries').validators],
dataRepositories: [{ value: this.dataRepositories, disabled: disabled }, context.getValidation('dataRepositories').validators]
});
return formGroup;
}
createValidationContext(): ValidationContext {
const baseContext: ValidationContext = new ValidationContext();
baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'label')] });
baseContext.validation.push({ key: 'profile', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'profile')] });
baseContext.validation.push({ key: 'uri', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'uri')] });
baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'status')] });
baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'description')] });
baseContext.validation.push({ key: 'services', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'services')] });
baseContext.validation.push({ key: 'registries', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'registries')] });
baseContext.validation.push({ key: 'dataRepositories', validators: [Validators.required, BackendErrorValidator(this.errorModel, 'dataRepositories')] });
return baseContext;
}
}

View File

@ -7,6 +7,7 @@ import { Observable } from 'rxjs/Observable';
import { DataTableRequest } from '../../models/data-table/DataTableRequest';
import { DataTableData } from '../../models/data-table/DataTableData';
import { DatasetListingModel } from '../../models/datasets/DatasetListingModel';
import { DatasetModel } from '../../models/datasets/DatasetModel';
@Injectable()
@ -28,7 +29,7 @@ export class DatasetService {
return this.http.post<DataTableData<DatasetListingModel>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
}
// getSingle(id: string): Observable<ProjectModel> {
// return this.http.get<ProjectModel>(this.actionUrl + id, { headers: this.headers });
// }
getSingle(id: string): Observable<DatasetModel> {
return this.http.get<DatasetModel>(this.actionUrl + id, { headers: this.headers });
}
}