Adds project tab and people tab

This commit is contained in:
apapachristou 2019-05-28 10:49:09 +03:00
parent 12372baa8f
commit cae43a14db
14 changed files with 257 additions and 75 deletions

View File

@ -5,6 +5,8 @@ import { ProjectListingModel } from "../project/project-listing";
import { ResearcherModel } from "../researcher/researcher";
import { UserModel } from "../user/user";
import { DmpDynamicField } from "./dmp-dynamic-field";
import { DatasetOverviewModel } from "../dataset/dataset-overview";
import { UserInfoListingModel } from "../user/user-info-listing";
export interface DmpModel {
id: string;
@ -15,11 +17,13 @@ export interface DmpModel {
status: Status;
lockable: boolean;
description: String;
profiles: DmpProfile[];
project: ProjectListingModel;
datasets: DatasetOverviewModel[];
profiles: DmpProfile[];
organisations: OrganizationModel[];
researchers: ResearcherModel[];
associatedUsers: UserModel[];
users: UserInfoListingModel[];
creator: UserModel;
definition: DmpProfileDefinition;
dynamicFields: Array<DmpDynamicField>;

View File

@ -2,4 +2,5 @@ export interface UserInfoListingModel {
id: String;
name: String;
role: number;
email: String;
}

View File

@ -4,4 +4,5 @@ export interface UserModel {
id: String;
name: String;
appRoles: AppRole[];
email: String;
}

View File

@ -25,6 +25,9 @@ import { DmpWizardDatasetListingComponent } from './wizard/listing/dmp-wizard-da
import { DmpOverviewComponent } from './overview/dmp-overview.component';
import { ExportMethodDialogModule } from '../../library/export-method-dialog/export-method-dialog.module';
import { GeneralTabComponent } from './editor/general-tab/general-tab.component';
import { PeopleTabComponent } from './editor/people-tab/people-tab.component';
import { ProjectTabComponent } from './editor/project-tab/project-tab.component';
import { DatasetsTabComponent } from './editor/datasets-tab/datasets-tab.component';
@NgModule({
imports: [
@ -55,7 +58,10 @@ import { GeneralTabComponent } from './editor/general-tab/general-tab.component'
DmpUploadDialogue,
DmpListingItemComponent,
DmpOverviewComponent,
GeneralTabComponent
GeneralTabComponent,
PeopleTabComponent,
ProjectTabComponent,
DatasetsTabComponent
],
entryComponents: [
DmpInvitationDialogComponent,

View File

@ -1,39 +1,39 @@
<div class="main-content">
<div class="container-fluid">
<div *ngIf="dmp" class="card">
<form *ngIf="formGroup" (ngSubmit)="formSubmit()">
<div class="card-header card-header-plain d-flex">
<div class="card-desc d-flex flex-column justify-content-center">
<h4 class="card-title">{{ dmp.label }}</h4>
</div>
<div class="d-flex ml-auto p-2">
<button mat-icon-button [matMenuTriggerFor]="actionsMenu" class="ml-auto more-icon"
(click)="$event.stopImmediatePropagation();">
<mat-icon class="more-horiz">more_horiz</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item *ngIf="!isPublic" (click)="newVersion(dmp.id, dmp.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="!isPublic" (click)="viewVersions(dmp.groupId, dmp.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="clone(dmp.id)" class="menu-item">
<mat-icon>add</mat-icon>{{ 'DMP-LISTING.ACTIONS.CLONE' | translate }}
</button>
<button mat-menu-item (click)="delete()" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
<button mat-menu-item (click)="advancedClicked()" class="menu-item">
<mat-icon>save_alt</mat-icon>{{ 'DMP-LISTING.ACTIONS.ADV-EXP' | translate }}
</button>
</mat-menu>
<button mat-raised-button color="primary" (click)="downloadPDF(dmp.id)"
class="lightblue-btn ml-2 text-uppercase">
<mat-icon>save_alt</mat-icon> {{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}
</button>
</div>
<div class="card-header card-header-plain d-flex">
<div class="card-desc d-flex flex-column justify-content-center">
<h4 class="card-title">{{ dmp.label }}</h4>
</div>
<div class="d-flex ml-auto p-2">
<button mat-icon-button [matMenuTriggerFor]="actionsMenu" class="ml-auto more-icon"
(click)="$event.stopImmediatePropagation();">
<mat-icon class="more-horiz">more_horiz</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item *ngIf="!isPublic" (click)="newVersion(dmp.id, dmp.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="!isPublic" (click)="viewVersions(dmp.groupId, dmp.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="clone(dmp.id)" class="menu-item">
<mat-icon>add</mat-icon>{{ 'DMP-LISTING.ACTIONS.CLONE' | translate }}
</button>
<button mat-menu-item (click)="delete()" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
<button mat-menu-item (click)="advancedClicked()" class="menu-item">
<mat-icon>save_alt</mat-icon>{{ 'DMP-LISTING.ACTIONS.ADV-EXP' | translate }}
</button>
</mat-menu>
<button mat-raised-button color="primary" (click)="downloadPDF(dmp.id)"
class="lightblue-btn ml-2 text-uppercase">
<mat-icon>save_alt</mat-icon> {{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}
</button>
</div>
</div>
<form *ngIf="formGroup" (ngSubmit)="formSubmit()">
<div class="d-flex flex-column">
<mat-tab-group class="mt-3">
<mat-tab>
@ -48,25 +48,28 @@
<mat-icon class="mr-2">work_outline</mat-icon>
{{ 'DMP-LISTING.COLUMNS.PROJECT' | translate }}
</ng-template>
<app-project-tab [formGroup]="formGroup"></app-project-tab>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="mr-2">library_books</mat-icon>
{{ 'DMP-LISTING.COLUMNS.DATASETS' | translate }}
</ng-template>
<app-datasets-tab [dmp]="dmp" ></app-datasets-tab>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="mr-2">person</mat-icon>
{{ 'DMP-LISTING.COLUMNS.PEOPLE' | translate }}
</ng-template>
<app-people-tab [people]="people" [dmp]="dmp"></app-people-tab>
</mat-tab>
<mat-tab>
<!-- <mat-tab>
<ng-template mat-tab-label>
<mat-icon class="mr-2">settings</mat-icon>
{{ 'DMP-LISTING.ACTIONS.SETTINGS' | translate }}
</ng-template>
</mat-tab>
</mat-tab> -->
</mat-tab-group>
<div class="d-flex justify-content-end pt-2 pb-4 pl-2 pr-2">

View File

@ -41,6 +41,7 @@ import { DmpEditorModel } from './dmp-editor.model';
import { DmpFinalizeDialogComponent } from './dmp-finalize-dialog/dmp-finalize-dialog.component';
import { AuthService } from '../../../core/services/auth/auth.service';
import { ExportMethodDialogComponent } from '../../../library/export-method-dialog/export-method-dialog.component';
import { UserInfoListingModel } from '../../../core/model/user/user-info-listing';
@Component({
selector: 'app-dmp-editor-component',
@ -58,11 +59,9 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
dmp: DmpEditorModel;
formGroup: FormGroup = null;
projectAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
createNewVersion;
associatedUsers: Array<UserModel>;
people: Array<UserInfoListingModel>;
filteredOptions: DmpProfileListing[];
selectedDmpProfileDefinition: DmpProfileDefinition;
DynamicDmpFieldResolverComponent: any;
@ -99,12 +98,12 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
const organisationRequestItem: RequestItem<BaseCriteria> = new RequestItem();
organisationRequestItem.criteria = new BaseCriteria();
this.projectAutoCompleteConfiguration = {
filterFn: this.searchProject.bind(this),
initialItems: (extraData) => this.searchProject(''),
displayFn: (item) => item['label'],
titleFn: (item) => item['label']
};
// this.projectAutoCompleteConfiguration = {
// filterFn: this.searchProject.bind(this),
// initialItems: (extraData) => this.searchProject(''),
// displayFn: (item) => item['label'],
// titleFn: (item) => item['label']
// };
if (itemId != null) {
this.isNew = false;
@ -131,6 +130,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
this.breadCrumbs = Observable.of(breadCrumbs);
}
this.associatedUsers = data.associatedUsers;
this.people = data.users;
});
} else if (projectId != null) {
this.isNew = true;
@ -203,12 +203,12 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
return this.dmpProfileService.getPaged(request).map(x => x.data);
}
searchProject(query: string) {
const projectRequestItem: RequestItem<ProjectCriteria> = new RequestItem();
projectRequestItem.criteria = new ProjectCriteria();
projectRequestItem.criteria.like = query;
return this.projectService.getWithExternal(projectRequestItem);
}
// searchProject(query: string) {
// const projectRequestItem: RequestItem<ProjectCriteria> = new RequestItem();
// projectRequestItem.criteria = new ProjectCriteria();
// projectRequestItem.criteria.like = query;
// return this.projectService.getWithExternal(projectRequestItem);
// }
formSubmit(): void {
//this.touchAllFormFields(this.formGroup);

View File

@ -12,6 +12,8 @@ import { ProjectListingModel } from "../../../core/model/project/project-listing
import { ResearcherModel } from "../../../core/model/researcher/researcher";
import { UserModel } from "../../../core/model/user/user";
import { ValidJsonValidator } from "../../../library/auto-complete/auto-complete-custom-validator";
import { DatasetOverviewModel } from "../../../core/model/dataset/dataset-overview";
import { UserInfoListingModel } from "../../../core/model/user/user-info-listing";
export class DmpEditorModel {
public id: string;
@ -27,7 +29,9 @@ export class DmpEditorModel {
public organisations: OrganizationModel[] = [];
public researchers: ResearcherModel[] = [];
public profiles: DmpProfile[] = [];
public datasets: DatasetOverviewModel[] = [];
public associatedUsers: UserModel[] = [];
public users: UserInfoListingModel[] = [];
public definition: DmpProfileDefinition;
public dynamicFields: Array<DmpDynamicFieldEditorModel> = [];
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
@ -45,7 +49,9 @@ export class DmpEditorModel {
this.organisations = item.organisations;
this.researchers = item.researchers;
this.profiles = item.profiles;
this.datasets = item.datasets;
this.associatedUsers = item.associatedUsers;
this.users = item.users;
if (item.definition) { this.definition = item.definition; }
if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); }
this.creator = item.creator;

View File

@ -22,19 +22,6 @@
translate}}</mat-error> -->
</mat-form-field>
</div>
<div class="row">
<!-- <mat-form-field class="col-8">
<app-single-auto-complete required='true' [formControl]="formGroup.get('project')"
placeholder="{{this.languageResolverService.getBy('dmpEditor') | translate}}"
[configuration]="projectAutoCompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('project').hasError('backendError')">
{{formGroup.get('project').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('project').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> -->
<!-- <app-dynamic-fields-project [formGroup]="formGroup"></app-dynamic-fields-project> -->
</div>
<div class="row">
<mat-form-field class="col-8">
<app-multiple-auto-complete required='true' [formControl]="formGroup.get('profiles')"
@ -93,17 +80,6 @@
<app-dynamic-dmp-field-resolver *ngIf="selectedDmpProfileDefinition" [formGroup]="formGroup"
[dmpProfileDefinition]="selectedDmpProfileDefinition">
</app-dynamic-dmp-field-resolver>
<!-- Associates Users -->
<!-- <div class="col-8">
<mat-list *ngIf="associatedUsers?.length" role="list" class="col-md-12">
<h3 mat-subheader>Associated Users</h3>
<mat-list-item role="listitem" *ngFor="let user of associatedUsers">
<mat-icon mat-list-icon>person</mat-icon>
<div>{{user.name}}</div>
</mat-list-item>
</mat-list>
</div> -->
</div>
<!-- Versioning Container-->

View File

@ -0,0 +1,33 @@
<div class="container-fluid">
<div class="row">
<div class="col-9 pt-4 pb-4 pl-4">
<div class="table-header col-auto d-flex mb-1">
<span class="table-title">Collaborators</span>
<div class="table-action" (click)="openShareDialog(dmp.id,dmp.label)">
<mat-icon>add</mat-icon><span>{{'DMP-LISTING.ACTIONS.INVITE' | translate}}</span>
</div>
</div>
<div class="table-container">
<table>
<tr>
<th>NAME</th>
<th>EMAIL</th>
<th>PERMISSIONS</th>
</tr>
<tr *ngFor="let user of people">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td>{{roleDisplay(user)}}</td>
</tr>
</table>
<!-- <mat-list *ngIf="associatedUsers?.length" role="list" class="col-12">
<h3 mat-subheader>Associated Users</h3>
<mat-list-item role="listitem" *ngFor="let user of associatedUsers">
<mat-icon mat-list-icon>person</mat-icon>
<div>{{user.name}}</div>
</mat-list-item>
</mat-list> -->
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,44 @@
.table-header {
background-color: #eeeeee;
color: #0070c0;
height: 2em;
}
.table-title {
align-self: center;
cursor: default;
}
.table-action {
display: flex;
margin-left: auto;
cursor: pointer;
}
.table-action span {
align-self: center;
}
.table-container {
border: 3px solid #f2f2f2;
margin-top: 0px;
padding: 0.5em;
cursor: default;
}
table {
width: 100%;
border-collapse: collapse;
color: black;
}
td {
padding: 8px;
text-align: left;
}
th {
background: linear-gradient(180deg, #f6f6f6, #fff);
padding: 8px;
text-align: left;
}

View File

@ -0,0 +1,50 @@
import { Component, OnInit, Input } from '@angular/core';
import { UserModel } from '../../../../core/model/user/user';
import { DmpEditorModel } from '../dmp-editor.model';
import { MatDialog } from '@angular/material';
import { DmpInvitationDialogComponent } from '../../invitation/dmp-invitation.component';
import { UserInfoListingModel } from '../../../../core/model/user/user-info-listing';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-people-tab',
templateUrl: './people-tab.component.html',
styleUrls: ['./people-tab.component.scss']
})
export class PeopleTabComponent implements OnInit {
@Input() associatedUsers: Array<UserModel>;
@Input() people: Array<UserInfoListingModel>;
@Input() dmp: DmpEditorModel;
constructor(
private dialog: MatDialog,
private translate: TranslateService
) { }
ngOnInit() {
}
openShareDialog(rowId: any, rowName: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
data: {
dmpId: rowId,
dmpName: rowName
}
});
}
roleDisplay(user: UserInfoListingModel) {
if (user.role === 0) {
return this.translate.instant('DMP-LISTING.OWNER');
}
else if (user.role === 1) {
return this.translate.instant('DMP-LISTING.MEMBER');
}
else {
return this.translate.instant('DMP-LISTING.OWNER');
}
}
}

View File

@ -0,0 +1,17 @@
<div class="container-fluid">
<div class="row">
<div class="col-9 pt-4 pb-4 pl-4">
<mat-form-field>
<app-single-auto-complete required='true' [formControl]="formGroup.get('project')"
placeholder="{{this.languageResolverService.getBy('dmpEditor') | translate}}"
[configuration]="projectAutoCompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('project').hasError('backendError')">
{{formGroup.get('project').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('project').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<!-- <app-dynamic-fields-project [formGroup]="formGroup"></app-dynamic-fields-project> -->
</div>
</div>

View File

@ -0,0 +1,41 @@
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { SingleAutoCompleteConfiguration } from '../../../../library/auto-complete/single/single-auto-complete-configuration';
import { RequestItem } from '../../../../core/query/request-item';
import { ProjectCriteria } from '../../../../core/query/project/project-criteria';
import { ProjectService } from '../../../../core/services/project/project.service';
import { LanguageResolverService } from '../../../../services/language-resolver/language-resolver.service';
@Component({
selector: 'app-project-tab',
templateUrl: './project-tab.component.html',
styleUrls: ['./project-tab.component.scss']
})
export class ProjectTabComponent implements OnInit {
@Input() formGroup: FormGroup = null;
projectAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
constructor(
private projectService: ProjectService,
public languageResolverService: LanguageResolverService
) { }
ngOnInit() {
this.projectAutoCompleteConfiguration = {
filterFn: this.searchProject.bind(this),
initialItems: (extraData) => this.searchProject(''),
displayFn: (item) => item['label'],
titleFn: (item) => item['label']
};
}
searchProject(query: string) {
const projectRequestItem: RequestItem<ProjectCriteria> = new RequestItem();
projectRequestItem.criteria = new ProjectCriteria();
projectRequestItem.criteria.like = query;
return this.projectService.getWithExternal(projectRequestItem);
}
}