# Conflicts:
#	dmp-frontend/src/app/app.module.ts
This commit is contained in:
Diamantis Tziotzios 2017-12-19 19:36:11 +02:00
commit 48539aac29
35 changed files with 488 additions and 183 deletions

View File

@ -12,6 +12,7 @@ import eu.eudat.managers.DatasetManager;
import eu.eudat.models.dataset.DatasetTableRequest;
import eu.eudat.models.helpers.DataTableData;
import eu.eudat.models.helpers.responses.*;
import eu.eudat.models.listingmodels.DatasetListingModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -41,7 +42,6 @@ import eu.eudat.dao.entities.UserInfoDao;
import eu.eudat.models.criteria.DataRepositoryCriteria;
import eu.eudat.models.criteria.RegistryCriteria;
import eu.eudat.models.criteria.ServiceCriteria;
import eu.eudat.responses.RestResponse;
@RestController
@ -66,14 +66,14 @@ public class Datasets {
@RequestMapping(method = RequestMethod.POST, value = { "/datasets/getPaged" }, consumes = "application/json", produces="application/json")
public @ResponseBody ResponseItem<DataTableData<eu.eudat.models.dataset.Dataset>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest) {
public @ResponseBody ResponseItem<DataTableData<DatasetListingModel>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest) {
try {
DataTableData<eu.eudat.models.dataset.Dataset> dataTable = new DatasetManager().getPaged(datasetDao, datasetTableRequest);
return new ResponseItem<DataTableData<eu.eudat.models.dataset.Dataset>>().status(HttpStatus.OK).payload(dataTable);
DataTableData<DatasetListingModel> dataTable = new DatasetManager().getPaged(datasetDao, datasetTableRequest);
return new ResponseItem<DataTableData<DatasetListingModel>>().status(HttpStatus.OK).payload(dataTable);
} catch (Exception ex) {
ex.printStackTrace();
return new ResponseItem<DataTableData<eu.eudat.models.dataset.Dataset>>().status(HttpStatus.OK).message(ex.getMessage());
return new ResponseItem<DataTableData<DatasetListingModel>>().status(HttpStatus.BAD_REQUEST).message(ex.getMessage());
}
}

View File

@ -10,6 +10,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
/**
* Created by ikalyvas on 12/15/2017.
*/
@ -23,6 +25,8 @@ public class Login {
@Autowired
private AuthenticationService authenticationService;
@Transactional
@RequestMapping(method = RequestMethod.POST, value = { "/externallogin" }, consumes = "application/json", produces="application/json")
public @ResponseBody ResponseItem<Principal> googleLogin(@RequestBody LoginInfo credentials) {
try {

View File

@ -51,7 +51,6 @@ import eu.eudat.entities.Researcher;
import eu.eudat.entities.Service;
import eu.eudat.entities.UserInfo;
import eu.eudat.helpers.Transformers;
import eu.eudat.responses.RestResponse;
@RestController

View File

@ -28,9 +28,13 @@ public class DatabaseContext<T extends DataEntity<T>> {
public T createOrUpdate(T item, Class<T> type) {
if (item.getKeys()[0] != null) {
T oldItem = entityManager.find(type, item.getKeys()[0]);
oldItem.update(item);
entityManager.merge(oldItem);
return oldItem;
if(oldItem!=null) {
oldItem.update(item);
entityManager.merge(oldItem);
return oldItem;
}else {
entityManager.persist(item);
}
} else entityManager.persist(item);
return item;
}

View File

@ -2,6 +2,7 @@ package eu.eudat.dao.entities.security;
import eu.eudat.dao.Dao;
import eu.eudat.entities.Credential;
import eu.eudat.entities.Project;
import eu.eudat.entities.UserToken;
import java.util.UUID;
@ -9,5 +10,8 @@ import java.util.UUID;
/**
* Created by ikalyvas on 12/15/2017.
*/
public interface CredentialDao extends Dao<Credential, UUID> {
public interface CredentialDao {
Credential createOrUpdate(Credential item);
}

View File

@ -1,8 +1,11 @@
package eu.eudat.dao.entities.security;
import eu.eudat.dao.JpaDao;
import eu.eudat.dao.databaselayer.service.DatabaseService;
import eu.eudat.entities.Credential;
import eu.eudat.entities.Project;
import eu.eudat.entities.UserToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
@ -11,9 +14,13 @@ import java.util.UUID;
* Created by ikalyvas on 12/15/2017.
*/
@Component("credentialDao")
public class CredentialDaoImpl extends JpaDao<Credential, UUID> implements CredentialDao {
public class CredentialDaoImpl implements CredentialDao {
@Autowired
DatabaseService<Credential> databaseService;
@Override
public Credential loadDetails(Credential credential) {
return null;
public Credential createOrUpdate(Credential item) {
return this.databaseService.createOrUpdate(item,Credential.class);
}
}

View File

@ -11,7 +11,7 @@ import java.util.UUID;
*/
@Entity
@Table(name="\"Credential\"")
public class Credential {
public class Credential implements DataEntity<Credential> {
@Id
@Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@ -113,4 +113,17 @@ public class Credential {
public int hashCode() {
return provider.intValue();
}
@Override
public void update(Credential entity) {
this.status = entity.status;
this.publicValue = entity.getPublicValue();
this.secret = entity.getSecret();
this.lastUpdateTime = new Date();
}
@Override
public Object[] getKeys() {
return new UUID[]{this.id == null ? null : this.id};
}
}

View File

@ -5,6 +5,7 @@ import eu.eudat.dao.entities.ProjectDao;
import eu.eudat.models.dataset.Dataset;
import eu.eudat.models.dataset.DatasetTableRequest;
import eu.eudat.models.helpers.DataTableData;
import eu.eudat.models.listingmodels.DatasetListingModel;
import eu.eudat.models.project.Project;
import eu.eudat.models.project.ProjectTableRequest;
import eu.eudat.queryable.QueryableList;
@ -18,11 +19,11 @@ import java.util.UUID;
*/
public class DatasetManager {
public DataTableData<Dataset> getPaged(DatasetDao datatasetRepository, DatasetTableRequest datasetTableRequest) throws IllegalAccessException, InstantiationException{
public DataTableData<DatasetListingModel> getPaged(DatasetDao datatasetRepository, DatasetTableRequest datasetTableRequest) throws IllegalAccessException, InstantiationException{
QueryableList<eu.eudat.entities.Dataset> items = datatasetRepository.getWithCriteria(datasetTableRequest.getCriteria());
QueryableList<eu.eudat.entities.Dataset> pagedItems = PaginationManager.applyPaging( items ,datasetTableRequest);
List<Dataset> datasets = new DomainModelConverter<eu.eudat.entities.Dataset, Dataset>().fromDataModel( pagedItems.toList(), eu.eudat.models.dataset.Dataset.class);
DataTableData<eu.eudat.models.dataset.Dataset> dataTable = new DataTableData<eu.eudat.models.dataset.Dataset>();
List<DatasetListingModel> datasets = new DomainModelConverter<eu.eudat.entities.Dataset, DatasetListingModel>().fromDataModel( pagedItems.toList(), DatasetListingModel.class);
DataTableData<DatasetListingModel> dataTable = new DataTableData<DatasetListingModel>();
dataTable.setData(datasets);
dataTable.setTotalCount(items.count());
return dataTable;

View File

@ -1,10 +1,11 @@
package eu.eudat.models.dataset;
import eu.eudat.models.DataModel;
import eu.eudat.utilities.helpers.LabelGenerator;
import java.util.Date;
public class DataRepository implements DataModel<eu.eudat.entities.DataRepository>{
public class DataRepository implements DataModel<eu.eudat.entities.DataRepository>,LabelGenerator{
private String pid;
private String name;
private String uri;
@ -49,4 +50,9 @@ public class DataRepository implements DataModel<eu.eudat.entities.DataRepositor
entity.setStatus((short)0);
return entity;
}
@Override
public String generateLabel() {
return this.getName();
}
}

View File

@ -1,12 +1,13 @@
package eu.eudat.models.dataset;
import eu.eudat.models.DataModel;
import eu.eudat.utilities.helpers.LabelGenerator;
import org.hibernate.annotations.Type;
import javax.persistence.Column;
import java.util.UUID;
public class Registry implements DataModel<eu.eudat.entities.Registry>{
public class Registry implements DataModel<eu.eudat.entities.Registry>,LabelGenerator {
private UUID id;
private String label;
private String abbreviation;
@ -34,6 +35,11 @@ public class Registry implements DataModel<eu.eudat.entities.Registry>{
return abbreviation;
}
@Override
public String generateLabel() {
return getLabel();
}
public void setAbbreviation(String abbreviation) {
this.abbreviation = abbreviation;
}

View File

@ -1,12 +1,13 @@
package eu.eudat.models.dataset;
import eu.eudat.models.DataModel;
import eu.eudat.utilities.helpers.LabelGenerator;
import org.hibernate.annotations.Type;
import javax.persistence.Column;
import java.util.UUID;
public class Service implements DataModel<eu.eudat.entities.Service>{
public class Service implements DataModel<eu.eudat.entities.Service>,LabelGenerator{
private UUID id;
private String label;
@ -79,4 +80,9 @@ public class Service implements DataModel<eu.eudat.entities.Service>{
eu.eudat.entities.Service entity = new eu.eudat.entities.Service();
return entity;
}
@Override
public String generateLabel() {
return this.label;
}
}

View File

@ -86,8 +86,8 @@ public class DataManagementPlanListingModel implements DataModel<DMP> {
this.label = entity.getLabel();
this.project = entity.getProject().getLabel();
this.profile = entity.getProfile().getLabel();
this.organisations =getLabel(new DomainModelConverter<eu.eudat.entities.Organisation,Organisation>().fromDataModel(entity.getOrganisations().stream().collect(Collectors.toList()),Organisation.class));
this.researchers =getLabel(new DomainModelConverter<eu.eudat.entities.Researcher,Researcher>().fromDataModel(entity.getResearchers().stream().collect(Collectors.toList()),Researcher.class));
this.organisations =LabelBuilder.getLabel(new DomainModelConverter<eu.eudat.entities.Organisation,Organisation>().fromDataModel(entity.getOrganisations().stream().collect(Collectors.toList()),Organisation.class));
this.researchers =LabelBuilder.getLabel(new DomainModelConverter<eu.eudat.entities.Researcher,Researcher>().fromDataModel(entity.getResearchers().stream().collect(Collectors.toList()),Researcher.class));
this.version = ""+entity.getVersion();
}
@ -96,7 +96,5 @@ public class DataManagementPlanListingModel implements DataModel<DMP> {
return null;
}
private <T extends LabelGenerator> String getLabel(List<T> items){
return LabelBuilder.generateLabel(items);
}
}

View File

@ -0,0 +1,137 @@
package eu.eudat.models.listingmodels;
import eu.eudat.entities.*;
import eu.eudat.entities.DataRepository;
import eu.eudat.entities.Dataset;
import eu.eudat.entities.Organisation;
import eu.eudat.entities.Registry;
import eu.eudat.entities.Researcher;
import eu.eudat.models.DataModel;
import eu.eudat.models.dataset.*;
import eu.eudat.models.dataset.Service;
import eu.eudat.models.dmp.*;
import eu.eudat.utilities.builders.DomainModelConverter;
import eu.eudat.utilities.helpers.LabelBuilder;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Created by ikalyvas on 12/19/2017.
*/
public class DatasetListingModel implements DataModel<Dataset> {
private String id;
private String label;
private String dmp;
private String profile;
private String dataRepositories;
private String registries;
private String services;
private String status;
private String created;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getDmp() {
return dmp;
}
public void setDmp(String dmp) {
this.dmp = dmp;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getDataRepositories() {
return dataRepositories;
}
public void setDataRepositories(String dataRepositories) {
this.dataRepositories = dataRepositories;
}
public String getRegistries() {
return registries;
}
public void setRegistries(String registries) {
this.registries = registries;
}
public String getServices() {
return services;
}
public void setServices(String services) {
this.services = services;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public void fromDataModel(Dataset entity) throws InstantiationException, IllegalAccessException {
this.id = entity.getId().toString();
this.label = entity.getLabel();
this.created = entity.getCreated().toString();
this.dmp = entity.getDmp()!=null? entity.getDmp().getLabel():"";
this.profile = entity.getProfile()!=null? entity.getProfile().getLabel():"";
this.description = entity.getDescription();
this.status = ""+entity.getStatus();
this.registries = LabelBuilder.getLabel(new DomainModelConverter<Registry, eu.eudat.models.dataset.Registry>().fromDataModel(entity.getRegistries().stream().collect(Collectors.toList()), eu.eudat.models.dataset.Registry.class));
this.dataRepositories = LabelBuilder.getLabel(new DomainModelConverter<eu.eudat.entities.DataRepository, eu.eudat.models.dataset.DataRepository>().fromDataModel(entity.getDataRepositories().stream().collect(Collectors.toList()), eu.eudat.models.dataset.DataRepository.class));
this.services = LabelBuilder.getLabel(new DomainModelConverter<eu.eudat.entities.Service, eu.eudat.models.dataset.Service>().fromDataModel(entity.getServices().stream().collect(Collectors.toList()), Service.class));
}
@Override
public Dataset toDataModel() {
return null;
}
}

View File

@ -1,32 +0,0 @@
package eu.eudat.responses;
public class RestResponse {
private String message;
private String objID;
public RestResponse(String message, String objID) {
super();
this.message = message;
this.objID = objID;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getObjID() {
return objID;
}
public void setObjID(String objID) {
this.objID = objID;
}
@Override
public String toString() {
return "{\"message\":\"" + message + "\", \"objID\":\"" + objID + "\"}";
}
}

View File

@ -1,6 +1,7 @@
package eu.eudat.security;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import javax.naming.NameAlreadyBoundException;
@ -32,7 +33,7 @@ public class CustomAuthenticationProvider {
@Autowired private GoogleTokenValidator googleTokenValidator;
@Autowired private NativeTokenValidator nativeTokenValidator;
public Principal authenticate(LoginInfo credentials) throws AuthenticationException {
public Principal authenticate(LoginInfo credentials) throws AuthenticationException, GeneralSecurityException {
String token = credentials.getTicket();
try {
Principal principal = googleTokenValidator.validateToken(token);

View File

@ -5,6 +5,8 @@ import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import com.google.api.client.googleapis.auth.oauth2.*;
import eu.eudat.dao.entities.security.CredentialDao;
@ -38,53 +40,39 @@ public class GoogleTokenValidator implements TokenValidator {
@Autowired private CredentialDao credentialDao;
@Autowired private AuthenticationService authenticationService;
@Autowired private UserTokenDao userTokenDao;
private GoogleTokenResponse verifyUser(String authCode) throws IOException {
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
"524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com",
"IQjhbYdExPIsjy37mOfB103F",
authCode,
"postmessage") // Specify the same redirect URI that you use with your web
// app. If you don't have a web version of your app, you can
// specify an empty string.
.execute();
return tokenResponse;
private GoogleIdTokenVerifier verifier;
public GoogleTokenValidator(){
verifier = new GoogleIdTokenVerifier.Builder(transport, JacksonFactory.getDefaultInstance())
.setAudience(Collections.singletonList("524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com"))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
}
private String getAccessToken(GoogleTokenResponse response){
return response.getAccessToken();
private GoogleIdToken verifyUserAndGetUser(String idTokenString) throws IOException, GeneralSecurityException {
GoogleIdToken idToken = verifier.verify(idTokenString);
return idToken;
}
private GoogleIdToken getUser(GoogleTokenResponse response) throws IOException {
return response.parseIdToken();
}
@Override
public eu.eudat.models.security.Principal validateToken(String authCode) throws NonValidTokenException, IOException {
GoogleTokenResponse tokenResponse = this.verifyUser(authCode);
String token = getAccessToken(tokenResponse);
GoogleIdToken idToken = getUser(tokenResponse);
public eu.eudat.models.security.Principal validateToken(String token) throws NonValidTokenException, IOException, GeneralSecurityException {
GoogleIdToken idToken = this.verifyUserAndGetUser(token);
Payload payload = idToken.getPayload();
UserInfo userInfo = userInfoDao.getByMail(payload.getEmail());
Credential credential = new Credential();
final Credential credential = new Credential();
credential.setCreationTime(new Date());
credential.setId(UUID.randomUUID());
credential.setStatus(1);
credential.setLastUpdateTime(new Date());
credential.setProvider(1);
credential.setSecret(token);
credential.setPublicValue(userInfo.getName());
credential.setUserInfo(userInfo);
credentialDao.create(credential);
if(userInfo == null) { //means not existing in db, so create one
if(userInfo == null) {
credential.setId(UUID.randomUUID());
userInfo = new UserInfo();
userInfo.setName((String)payload.get("name"));
userInfo.setVerified_email(payload.getEmailVerified());
@ -94,14 +82,24 @@ public class GoogleTokenValidator implements TokenValidator {
userInfo.setAuthorization_level(new Short("1"));
userInfo.setUsertype(new Short("1"));
userInfo = userInfoDao.create(userInfo);
credential = credentialDao.create(credential);
credential.setUserInfo(userInfo);
credentialDao.createOrUpdate(credential);
}
else {
userInfo.setLastloggedin(new Date());
Set<Credential> credentials = userInfo.getCredentials();
if(credentials.contains(credential))credentials.remove(credential);
credentials.add(credential);
if(credentials.contains(credential)){
Credential oldCredential = credentials.stream().filter(item->credential.getProvider().equals(item.getProvider())).findFirst().get();
credential.setId(oldCredential.getId());
}
else{
credential.setUserInfo(userInfo);
credential.setId(UUID.randomUUID());
credentialDao.createOrUpdate(credential);
userInfo.getCredentials().add(credential);
}
userInfo = userInfoDao.update(userInfo);
}
UserToken userToken = new UserToken();

View File

@ -5,9 +5,10 @@ import eu.eudat.exceptions.NonValidTokenException;
import eu.eudat.models.security.Principal;
import java.io.IOException;
import java.security.GeneralSecurityException;
public interface TokenValidator {
public Principal validateToken(String token) throws NonValidTokenException, IOException;
public Principal validateToken(String token) throws NonValidTokenException, IOException, GeneralSecurityException;
}

View File

@ -6,16 +6,22 @@ import java.util.List;
* Created by ikalyvas on 12/19/2017.
*/
public class LabelBuilder {
public static <T extends LabelGenerator> String generateLabel(List<T> items){
private static <T extends LabelGenerator> String generateLabel(List<T> items){
String label="";
for(T item : items){
if(items.indexOf(item)==3){
label+="...";
break;
}
if(items.indexOf(item)>1){
label+=", ";
}
label+=item.generateLabel();
}
return label;
}
public static <T extends LabelGenerator> String getLabel(List<T> items){
return generateLabel(items);
}
}

View File

@ -11,6 +11,8 @@ import { ProjectListingComponent } from './projects/project-listing.component';
import { DataManagementPlanListingComponent } from './dmps/dmp-listing.component';
import { ProjectEditorComponent } from './projects/editor/project-editor.component';
import { DataManagementPlanEditorComponent } from './dmps/editor/dmp-editor.component';
import { DatasetEditorComponent } from './datasets_new/editor/dataset-editor.component';
import { DatasetListingComponent } from './datasets_new/dataset-listing.component';
import { DataManagementPlanWizardComponent } from './dmp-wizard/dmp-wizard.component';
import { LoginComponent } from './login/login.component';
@ -25,7 +27,10 @@ const appRoutes: Routes = [
{ path: 'dmp/new', component: DataManagementPlanWizardComponent, canActivate: [AuthGuard]},
{ path: 'dmp/:id', component: DataManagementPlanEditorComponent, canActivate: [AuthGuard]},
{ path: 'dmps/new', component: DataManagementPlanEditorComponent, canActivate: [AuthGuard]},
{ path: 'datasets', component: DatasetListingComponent, canActivate: [AuthGuard]},
{ path: 'dataset/:id', component: DatasetEditorComponent, canActivate: [AuthGuard]},
{ path: 'datasets/new', component: DatasetEditorComponent, canActivate: [AuthGuard]},
{ path: 'login', component: LoginComponent},
{ path: "unauthorized", loadChildren: './unauthorized/unauthorized.module#UnauthorizedModule' },
{ path: 'welcome', component: HomepageComponent, canActivate: [AuthGuard]},

View File

@ -58,6 +58,7 @@ import { BaseHttpService } from './utilities/cite-http-service-module/base-http.
import { DataManagementPlanListingComponent } from './dmps/dmp-listing.component';
import { ProjectEditorComponent } from './projects/editor/project-editor.component';
import { DataManagementPlanEditorComponent } from './dmps/editor/dmp-editor.component';
import { DatasetEditorComponent } from './datasets_new/editor/dataset-editor.component';
import { DataManagementPlanWizardComponent } from './dmp-wizard/dmp-wizard.component';
import { LoginComponent } from './login/login.component';
import { FigurecardComponent } from './shared/components/figurecard/figurecard.component';
@ -92,7 +93,8 @@ import { FigurecardComponent } from './shared/components/figurecard/figurecard.c
ProjectEditorComponent,
DataManagementPlanEditorComponent,
DataManagementPlanWizardComponent,
FigurecardComponent
FigurecardComponent,
DatasetEditorComponent
],
imports: [
BrowserModule,

View File

@ -13,22 +13,41 @@
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
</ng-container>
<!-- Column Definition: Reference -->
<ng-container cdkColumnDef="reference">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.REFERNCE' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.reference}} </mat-cell>
<!-- Column Definition: Dmp -->
<ng-container cdkColumnDef="dmp">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.DMP' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.dmp}} </mat-cell>
</ng-container>
<!-- Column Definition: Uri -->
<ng-container cdkColumnDef="uri">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.URI' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.uri}} </mat-cell>
<!-- Column Definition: Profile -->
<ng-container cdkColumnDef="profile">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.PROFILE' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.profile}} </mat-cell>
</ng-container>
<!-- Column Definition: DataRepositories -->
<ng-container cdkColumnDef="dataRepositories">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.DATAREPOSITORIES' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.dataRepositories}} </mat-cell>
</ng-container>
<!-- Column Definition: DataRepositories -->
<ng-container cdkColumnDef="registries">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.REGISTRIES' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.registries}} </mat-cell>
</ng-container>
<!-- Column Definition: DataRepositories -->
<ng-container cdkColumnDef="services">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.SERVICES' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.services}} </mat-cell>
</ng-container>
<!-- Column Definition: Status -->
<ng-container cdkColumnDef="status">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.STATUS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.status}} </mat-cell>
<mat-cell *matCellDef="let row"> {{row.status}}
</mat-cell>
</ng-container>
<!-- Column Definition: Description -->
@ -53,13 +72,11 @@
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="rowClick(row.id)"></mat-row>
</mat-table>
<mat-paginator #paginator
[length]="dataSource?.totalCount"
[pageSizeOptions]="[10, 25, 100]">
<mat-paginator #paginator [length]="dataSource?.totalCount" [pageSizeOptions]="[10, 25, 100]">
</mat-paginator>
</mat-card>
<button mat-fab class="mat-fab-bottom-right" color="primary" [routerLink]=" ['./new'] ">
<mat-icon class="mat-24">add</mat-icon>
</button>
</div>
</div>

View File

@ -20,15 +20,20 @@ import { DatasetListingModel } from "../models/datasets/DatasetListingModel";
styleUrls: ['./dataset-listing.component.scss'],
providers: [DatasetService]
})
export class DatasetListingComponent implements OnInit, AfterViewInit {
export class DatasetListingComponent implements OnInit {
@ViewChild(MatPaginator) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(DatasetCriteriaComponent) criteria: DatasetCriteriaComponent;
dataSource: DatasetDataSource | null;
displayedColumns: String[] = ['label', 'reference', 'uri', 'status', 'description', 'created', 'actions'];
displayedColumns: String[] = ['label','dmp' ,'profile' , 'dataRepositories', 'registries','services', 'status', 'description', 'created', 'actions'];
statuses = [
{value: '0', viewValue: 'Active'},
{value: '1', viewValue: 'Inactive'}
];
constructor(
private datasetService: DatasetService,
private router: Router,
@ -39,14 +44,9 @@ export class DatasetListingComponent implements OnInit, AfterViewInit {
}
ngOnInit() {
}
ngAfterViewInit() {
setTimeout(() => {
this.criteria.setRefreshCallback(() => this.refresh());
this.criteria.setCriteria(this.getDefaultCriteria());
});
this.criteria.setCriteria(this.getDefaultCriteria());
this.refresh();
this.criteria.setRefreshCallback(() => this.refresh());
}
refresh() {
@ -54,7 +54,7 @@ export class DatasetListingComponent implements OnInit, AfterViewInit {
}
rowClick(rowId: String) {
this.router.navigate(['/project/' + rowId]);
this.router.navigate(['/dataset/' + rowId]);
}
getDefaultCriteria(): DatasetCriteria {
@ -112,7 +112,7 @@ export class DatasetDataSource extends DataSource<DatasetListingModel> {
setTimeout(() => {
this.isLoadingResults = false;
});
return result.payload;
return result;
})
.map(result => {
if (!result) { return []; }

View File

@ -1,28 +1,28 @@
<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-title *ngIf="isNew">{{'DATASET-EDITOR.TITLE.NEW' | translate}}</mat-card-title>
<mat-card-title *ngIf="!isNew">{{'DATASET-EDITOR.TITLE.EDIT' | translate}} {{dataset.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>
<input matInput placeholder="{{'DATASET-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"
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.PROFILE' | translate}}" type="text" name="profile" formControlName="profile"
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-error *ngIf="formGroup.get('profile').errors?.backendError">{{baseErrorModel.profile}}</mat-error>
<mat-error *ngIf="formGroup.get('profile').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>
<input matInput placeholder="{{'DATASET-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> -->
</mat-form-field>
<!-- <table class="input-table full-width">
<tr>
@ -50,14 +50,14 @@
</table> -->
<mat-form-field class="full-width">
<textarea matInput class="description-area" placeholder="{{'DMP-EDITOR.FIELDS.DESCRIPTION' | translate}}" formControlName="description"
<textarea matInput class="description-area" placeholder="{{'DATASET-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>
<td-chips color="accent" [items]="filtereddataRepositories" formControlName="dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}"
(inputChange)="filterdataRepositories($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}}
@ -67,13 +67,13 @@
{{option.name}}
</div>
</ng-template>
<mat-progress-bar [style.height.px]="2" *ngIf="filteringOrganisationsAsync" mode="indeterminate"></mat-progress-bar>
<mat-progress-bar [style.height.px]="2" *ngIf="filtereddataRepositoriesAsync" 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>
<td-chips color="accent" [items]="filteredRegistries" formControlName="registries" placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}"
(inputChange)="filterRegistries($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>
<div class="tc-grey-100 bgc-teal-700" td-chip-avatar>{{chip.label.substring(0, 1).toUpperCase()}}</div>
{{chip.name}}
</ng-template>
<ng-template td-autocomplete-option let-option="option">
@ -81,13 +81,27 @@
{{option.name}}
</div>
</ng-template>
<mat-progress-bar [style.height.px]="2" *ngIf="filteringResearchersAsync" mode="indeterminate"></mat-progress-bar>
<mat-progress-bar [style.height.px]="2" *ngIf="filteredRegistriesAsync" mode="indeterminate"></mat-progress-bar>
</td-chips>
<td-chips color="accent" [items]="filteredServices" formControlName="services" placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}"
(inputChange)="filteredServices($event)" requireMatch>
<ng-template td-chip let-chip="chip">
<div class="tc-grey-100 bgc-teal-700" td-chip-avatar>{{chip.label.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>
<button mat-raised-button color="primary" (click)="cancel()" type="button">{{'DATASET-EDITOR.ACTIONS.CANCEL' | translate}}</button>
<button mat-raised-button color="primary" type="submit">{{'DATASET-EDITOR.ACTIONS.SAVE' | translate}}</button>
<button *ngIf="!isNew" mat-raised-button color="primary" type="submit" (click)="delete()">{{'DATASET-EDITOR.ACTIONS.DELETE' | translate}}</button>
</div>
</mat-card-content>

View File

@ -18,20 +18,20 @@ import { ExternalSourcesItemModel } from "../../models/external-sources/External
@Component({
selector: 'app-dataset-editor-component',
templateUrl: 'dataset-editor.component.html',
styleUrls: ['./dataset-editor.component.scss'],
styleUrls: ['./dataset-editor.component.css'],
providers: [DatasetService, ExternalSourcesService],
encapsulation: ViewEncapsulation.None
})
export class DatasetEditorComponent implements AfterViewInit {
isNew = true;
dataManagementPlan: DatasetModel;
dataset: DatasetModel;
formGroup: FormGroup = null;
filteringOrganisationsAsync: boolean = false;
filteringResearchersAsync: boolean = false;
filteredOrganisations: ExternalSourcesItemModel[];
filteredResearchers: ExternalSourcesItemModel[];
filtereddataRepositoriesAsync: boolean = false;
filteredRegistriesAsync: boolean = false;
filtereddataRepositories: ExternalSourcesItemModel[];
filteredRegistries: ExternalSourcesItemModel[];
constructor(
private datasetService: DatasetService,
@ -52,13 +52,13 @@ export class DatasetEditorComponent implements AfterViewInit {
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();
this.dataset = new JsonSerializer<DatasetModel>().fromJSONObject(data, DatasetModel);
this.formGroup = this.dataset.buildForm();
});
} else {
this.dataManagementPlan = new DatasetModel();
this.dataset = new DatasetModel();
setTimeout(() => {
this.formGroup = this.dataManagementPlan.buildForm();
this.formGroup = this.dataset.buildForm();
});
}
});
@ -87,7 +87,7 @@ export class DatasetEditorComponent implements AfterViewInit {
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dataManagementPlans']);
this.router.navigate(['/datasets']);
}
onCallbackError(error: any) {
@ -97,23 +97,23 @@ export class DatasetEditorComponent implements AfterViewInit {
public setErrorModel(errorModel: BaseErrorModel) {
Object.keys(errorModel).forEach(item => {
(<any>this.dataManagementPlan.errorModel)[item] = (<any>errorModel)[item];
(<any>this.dataset.errorModel)[item] = (<any>errorModel)[item];
})
}
public cancel(): void {
this.router.navigate(['/dataManagementPlans']);
this.router.navigate(['/datasets']);
}
filterOrganisations(value: string): void {
filterdataRepositories(value: string): void {
this.filteredOrganisations = undefined;
this.filtereddataRepositories = undefined;
if (value) {
this.filteringOrganisationsAsync = true;
this.filtereddataRepositoriesAsync = true;
this.externalSourcesService.searchDMPOrganizations(value).subscribe(items => {
this.filteredOrganisations = items;
this.filteringOrganisationsAsync = false;
this.filtereddataRepositories = items;
this.filtereddataRepositoriesAsync = false;
// this.filteredOrganisations = items.filter((filteredObj: any) => {
// return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true;
@ -123,15 +123,15 @@ export class DatasetEditorComponent implements AfterViewInit {
}
}
filterResearchers(value: string): void {
filterRegistries(value: string): void {
this.filteredResearchers = undefined;
this.filteredRegistries = undefined;
if (value) {
this.filteringResearchersAsync = true;
this.filteredRegistriesAsync = true;
this.externalSourcesService.searchDMPResearchers(value).subscribe(items => {
this.filteredResearchers = items;
this.filteringResearchersAsync = false;
this.filteredRegistries = items;
this.filteredRegistriesAsync = false;
// this.filteredOrganisations = items.filter((filteredObj: any) => {
// return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true;

View File

@ -1,6 +1,5 @@
import { BaseCriteria } from "../BaseCriteria";
export class DatasetCriteria extends BaseCriteria {
public Name: String;
public Status: Number;
public status: Number;
}

View File

@ -1,6 +1,5 @@
import { BaseCriteriaErrorModel } from "../BaseCriteriaErrorModel";
export class DatasetCriteriaErrorModel extends BaseCriteriaErrorModel{
public Name: String;
public Status: Number;
public status: Number;
}

View File

@ -0,0 +1,17 @@
import { Serializable } from "../Serializable";
export class DataRepositoryModel implements Serializable<DataRepositoryModel> {
public id: String;
public name: String;
public pid: String;
public uri: String;
fromJSONObject(item: any): DataRepositoryModel {
this.id = item.id;
this.name = item.name;
this.pid = item.pid;
this.uri = item.uri;
return this;
}
}

View File

@ -2,18 +2,28 @@ import { Serializable } from "../Serializable";
export class DatasetListingModel implements Serializable<DatasetListingModel> {
public id: String;
public label:String;
public reference: String;
public uri: String;
public label:String;
public dmp: String;
public profile: String;
public dataRepositories: String;
public registries: String;
public services: String;
public description: String;
public status: Number;
public created: Date;
//public uri: String;
// public reference: String;
fromJSONObject(item: any): DatasetListingModel {
this.id = item.id;
this.label = item.label;
this.reference = item.reference;
this.uri = item.uri;
this.dmp = item.dmp;
this.profile = item.profile;
this.dataRepositories = item.dataRepositories;
this.registries = item.registries;
this.services = item.services;
//this.reference = item.reference;
//this.uri = item.uri;
this.status = item.status;
this.description = item.description;
this.created = item.created;

View File

@ -5,6 +5,10 @@ import { BackendErrorValidator } from "../../utilities/validators/BackendErrorVa
import { BaseErrorModel } from "../error/BaseErrorModel";
import { AutoCompleteItem } from "../../shared/components/autocomplete/AutoCompleteItem";
import { ExternalSourcesItemModel } from "../external-sources/ExternalSourcesItemModel";
import { ServiceModel } from "../services/ServiceModel";
import { JsonSerializer } from "../../utilities/JsonSerializer";
import { RegisterModel } from "../registers/RegisterModel";
import { DataRepositoryModel } from "../dataRepositories/DataRepositoryModel";
export class DatasetModel implements Serializable<DatasetModel> {
public id: String;
@ -13,9 +17,9 @@ export class DatasetModel implements Serializable<DatasetModel> {
public uri: String;
public status: String;
public description: String;
public services: ExternalSourcesItemModel[] = [];
public registries: ExternalSourcesItemModel[] = [];
public dataRepositories: ExternalSourcesItemModel[] = [];
public services: ServiceModel[] = [];
public registries: RegisterModel[] = [];
public dataRepositories: DataRepositoryModel[] = [];
public errorModel: BaseErrorModel = new BaseErrorModel();
@ -26,6 +30,9 @@ export class DatasetModel implements Serializable<DatasetModel> {
this.uri = item.uri;
this.status = item.status;
this.description = item.description;
this.services = new JsonSerializer<ServiceModel>().fromJSONArray(item.services, ServiceModel);
this.registries = new JsonSerializer<RegisterModel>().fromJSONArray(item.registries, RegisterModel);
this.dataRepositories = new JsonSerializer<DataRepositoryModel>().fromJSONArray(item.dataRepositories, DataRepositoryModel);
return this;
}

View File

@ -0,0 +1,21 @@
import { Serializable } from "../Serializable";
export class RegisterModel implements Serializable<RegisterModel> {
public abbreviation: String;
public definition: String;
public id: String;
public label: String;
public reference: String;
public uri: String;
fromJSONObject(item: any): RegisterModel {
this.abbreviation = item.abbreviation;
this.definition = item.definition;
this.id = item.id;
this.label = item.label;
this.reference = item.reference;
this.uri = item.uri;
return this;
}
}

View File

@ -0,0 +1,21 @@
import { Serializable } from "../Serializable";
export class ServiceModel implements Serializable<ServiceModel> {
public id: String;
public abbreviation: String;
public definition: String;
public uri: String;
public label: String;
public reference: String;
fromJSONObject(item: any): ServiceModel {
this.id = item.id;
this.abbreviation = item.abbreviation;
this.definition = item.definition;
this.uri = item.uri;
this.label = item.label;
this.reference = item.reference;
return this;
}
}

View File

@ -31,7 +31,7 @@ export class DatasetService {
}
getSingle(id: string): Observable<DatasetModel> {
return this.http.get<DatasetModel>(this.actionUrl + id, { headers: this.headers });
return this.http.get<DatasetModel>(this.actionUrl +'getSingle/' + id, { headers: this.headers });
}
createDataset(datasetModel: DatasetModel): Observable<DatasetModel> {

View File

@ -17,16 +17,20 @@
</div> -->
<div class="col-sm-6 col-md-2">
<mat-form-field>
<input matInput placeholder=" {{'CRITERIA.PROJECTS.LIKE'| translate}}" name="datasetCriteriaName" [(ngModel)]="criteria.Name"
<input matInput placeholder=" {{'CRITERIA.PROJECTS.LIKE'| translate}}" name="datasetCriteriaName" [(ngModel)]="criteria.like"
(ngModelChange)="controlModified()">
<mat-error *ngIf="baseErrorModel?.name">{{baseErrorModel['Criteria.Name']}}</mat-error>
<mat-error *ngIf="baseErrorModel?.name">{{baseErrorModel['Criteria.like']}}</mat-error>
</mat-form-field>
</div>
<div class="col-sm-6 col-md-2">
<mat-form-field>
<input matInput placeholder=" {{'CRITERIA.DATA-SETS.STATUS'| translate}}" name="datasetCriteriastatus" [(ngModel)]="criteria.Status"
(ngModelChange)="controlModified()">
<mat-error *ngIf="baseErrorModel?.status">{{baseErrorModel['Criteria.Status']}}</mat-error>
<mat-select placeholder=" {{'CRITERIA.DATA-SETS.STATUS'| translate}}" name="datasetCriteriastatus" [(ngModel)]="criteria.status"
(ngModelChange)="controlModified()">
<mat-option *ngFor="let status of statuses" [value]="status.value">
{{status.viewValue}}
</mat-option>
</mat-select>
<mat-error *ngIf="baseErrorModel?.status">{{baseErrorModel['Criteria.status']}}</mat-error>
</mat-form-field>
</div>
</div>

View File

@ -21,6 +21,11 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O
// public formStatus: ProjectStatus;
public criteria: DatasetCriteria= new DatasetCriteria();
statuses = [
{value: '0', viewValue: 'Active'},
{value: '1', viewValue: 'Inactive'}
];
constructor(
public language: TranslateService,
public formBuilder: FormBuilder

View File

@ -43,7 +43,12 @@
"STATUS": "Status",
"DESCRIPTION": "Description",
"CREATED": "Created",
"ACTIONS": "Actions"
"ACTIONS": "Actions",
"DMP": "Dmp",
"PROFILE": "Profile",
"DATAREPOSITORIES": "Data Repositories",
"REGISTRIES": "Registries",
"SERVICES": "Services"
}
},
"PROJECT-EDITOR": {
@ -98,5 +103,25 @@
"LIKE": "Search",
"PROJECTS": "Projects"
}
},
"DATASET-EDITOR": {
"TITLE": {
"NEW": "New Data Management Plan",
"EDIT": "Edit"
},
"FIELDS": {
"NAME": "Name",
"DESCRIPTION": "Description",
"PROFILE": "Profile",
"URI": "Uri",
"DATAREPOSITORIES": "Data Repositories",
"REGISTRIES": "Registries",
"SERVICES": "Services"
},
"ACTIONS": {
"SAVE": "Save",
"CANCEL": "Cancel",
"DELETE": "Delete"
}
}
}