no message
This commit is contained in:
parent
86db30e5f3
commit
9f324b9f19
File diff suppressed because it is too large
Load Diff
|
@ -12,17 +12,17 @@
|
|||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^4.2.4",
|
||||
"@angular/cdk": "^5.1.1",
|
||||
"@angular/common": "^4.2.4",
|
||||
"@angular/compiler": "^4.2.4",
|
||||
"@angular/core": "^4.2.4",
|
||||
"@angular/forms": "^4.2.4",
|
||||
"@angular/http": "^4.2.4",
|
||||
"@angular/material": "^5.1.1",
|
||||
"@angular/platform-browser": "^4.2.4",
|
||||
"@angular/platform-browser-dynamic": "^4.2.4",
|
||||
"@angular/router": "^4.2.4",
|
||||
"@angular/animations": "^5.1.1",
|
||||
"@angular/cdk": "^5.0.1",
|
||||
"@angular/common": "5.1.1",
|
||||
"@angular/compiler": "5.1.1",
|
||||
"@angular/core": "5.1.1",
|
||||
"@angular/forms": "5.1.1",
|
||||
"@angular/http": "5.1.1",
|
||||
"@angular/material": "^5.0.1",
|
||||
"@angular/platform-browser": "5.1.1",
|
||||
"@angular/platform-browser-dynamic": "5.1.1",
|
||||
"@angular/router": "5.1.1",
|
||||
"@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
|
||||
"angular-datatables": "^4.4.0",
|
||||
"angular2-datatable": "^0.6.0",
|
||||
|
@ -33,15 +33,15 @@
|
|||
"jquery": "^3.2.1",
|
||||
"ng2-bootstrap-modal": "^1.0.1",
|
||||
"ng2-simple-global": "^1.2.5",
|
||||
"ngx-contextmenu": "^1.3.5",
|
||||
"ngx-webstorage": "^1.8.0",
|
||||
"rxjs": "^5.4.2",
|
||||
"zone.js": "^0.8.14"
|
||||
"zone.js": "^0.8.14",
|
||||
"@ngx-translate/core": "^9.0.1",
|
||||
"@ngx-translate/http-loader": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.3.1",
|
||||
"@angular/compiler-cli": "^4.2.4",
|
||||
"@angular/language-service": "^4.2.4",
|
||||
"@angular/cli": "1.6.5",
|
||||
"@angular/compiler-cli": "^5.1.1",
|
||||
"@angular/language-service": "^5.1.1",
|
||||
"@types/jasmine": "~2.5.53",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/jquery": "^3.2.12",
|
||||
|
@ -58,6 +58,6 @@
|
|||
"protractor": "~5.1.2",
|
||||
"ts-node": "~3.2.0",
|
||||
"tslint": "~5.3.2",
|
||||
"typescript": "~2.3.3"
|
||||
"typescript": "2.4.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export const HostConfiguration = {
|
||||
Server: 'http://192.168.32.67:8080/', //'http://dl043.madgik.di.uoa.gr:8080/'
|
||||
App: 'localhost:4200/' // 'http://dl043.madgik.di.uoa.gr:8080/'
|
||||
//CASHost: 'https://login-devel.uoa.gr/login',
|
||||
//Service: 'http://elkefinman/login'
|
||||
}
|
|
@ -20,8 +20,6 @@ import { DataTableModule } from "angular2-datatable";
|
|||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { DialogService } from "ng2-bootstrap-modal";
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { ContextMenuModule } from 'ngx-contextmenu';
|
||||
import { Ng2Webstorage } from 'ngx-webstorage';
|
||||
|
||||
import { RestBase } from './services/rest-base';
|
||||
import { TokenService } from './services/login/token.service';
|
||||
|
@ -127,8 +125,6 @@ import { DatasetProfileModule } from './dataset-profile-form/dataset-profile.mod
|
|||
DataTableModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ContextMenuModule,
|
||||
Ng2Webstorage,
|
||||
NgbModule.forRoot(),
|
||||
AppRouting
|
||||
],
|
||||
|
|
|
@ -28,6 +28,6 @@ export class RadioBoxComponent implements OnInit{
|
|||
(<FormArray>this.form.get("data").get("options")).push(radioListOptions.buildForm());
|
||||
this.data.options = [];
|
||||
this.data.options.push(radioListOptions);
|
||||
this.dataModel.data = new JsonSerializer<RadioBoxData>().fromJSONObject(this.data,RadioBoxData);
|
||||
this.dataModel.data = JsonSerializer.fromJSONObject(this.data,RadioBoxData);
|
||||
}
|
||||
}
|
|
@ -29,6 +29,6 @@ export class WordlistComponent implements OnInit{
|
|||
(<FormArray>this.form.get("data").get("options")).push(wordListOptions.buildForm());
|
||||
this.data.options = [];
|
||||
this.data.options.push(wordListOptions);
|
||||
this.dataModel.data = new JsonSerializer<WordListData>().fromJSONObject(this.data,WordListData);
|
||||
this.dataModel.data = JsonSerializer.fromJSONObject(this.data,WordListData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { MaterialModule } from '../material/material.module';
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MaterialModule,
|
||||
]
|
||||
})
|
||||
|
||||
export class CoreModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: CoreModule,
|
||||
providers: [
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export class Criteria {
|
||||
public Like: string;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { Criteria } from './Criteria';
|
||||
import { Principal } from '../../models/login/Principal';
|
||||
|
||||
export class UserCriteria extends Criteria {
|
||||
public Label: String;
|
||||
public Roles: Principal.AppRole[];
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { UserListingModel } from '../../shared/components/criteria/models/errormodel/users/userListingModel';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { DataTableRequest } from '../../models/data-table/dataTableRequest';
|
||||
import { DataTableData } from '../../models/data-table/dataTableData';
|
||||
import { MyHttpService } from 'app/utilities/httpservice/myhttpservice.service';
|
||||
import { HostConfiguration } from 'app/app.constants';
|
||||
|
||||
@Injectable()
|
||||
export class UserReferenceService {
|
||||
|
||||
private actionUrl: string;
|
||||
private headers: HttpHeaders;
|
||||
|
||||
constructor(private http: MyHttpService) {
|
||||
|
||||
this.actionUrl = HostConfiguration.Server + 'api/user/';
|
||||
|
||||
this.headers = new HttpHeaders();
|
||||
this.headers = this.headers.set('Content-Type', 'application/json');
|
||||
this.headers = this.headers.set('Accept', 'application/json');
|
||||
}
|
||||
|
||||
// formatItem(utilities: Utilities, item: ConfigurationModel): ConfigurationModel {
|
||||
// item.validFrom = new Date(item.validFrom);
|
||||
// item.validTo = new Date(item.validTo);
|
||||
// return item
|
||||
// }
|
||||
|
||||
getPaged(dataTableRequest: DataTableRequest): Observable<DataTableData<UserListingModel>> {
|
||||
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
|
||||
}
|
||||
|
||||
updateRoles(itemToUpdate: UserListingModel): Observable<UserListingModel> {
|
||||
return this.http.post<UserListingModel>(this.actionUrl + 'updateRoles', JSON.stringify(itemToUpdate), { headers: this.headers });
|
||||
}
|
||||
|
||||
delete(id: String): Observable<any> {
|
||||
return this.http.delete<any>(this.actionUrl + id, { headers: this.headers });
|
||||
}
|
||||
}
|
|
@ -57,7 +57,7 @@ export class SectionFormComponent {
|
|||
|
||||
keepPageSelectionValid(pagesJson: Array<any>) {
|
||||
let selectedPage = this.form.get("page").value as String;
|
||||
let pages: Array<Page> = new JsonSerializer<Page>().fromJSONArray(pagesJson, Page);
|
||||
let pages: Array<Page> = JsonSerializer.fromJSONArray(pagesJson, Page);
|
||||
if (pages.find(elem => elem.id === selectedPage) === undefined)
|
||||
this.form.get("page").reset();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { DatasetProfileService } from '../../services/dataset-profile.service';
|
||||
import { ContextMenuComponent } from 'ngx-contextmenu';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
|
@ -130,6 +129,4 @@ export class DatasetprofileEditorComponent implements OnInit {
|
|||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { DmpProfileService } from '../../services/dmpprofile-service';
|
||||
import { ContextMenuComponent } from 'ngx-contextmenu';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
|
@ -128,9 +127,6 @@ export class DmpProfileEditorComponent implements OnInit {
|
|||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { NativeDateAdapter } from '@angular/material';
|
||||
|
||||
|
||||
export class LocalizedDateAdapter extends NativeDateAdapter {
|
||||
|
||||
parse(value: any): Date | null {
|
||||
const invalidDate = new Date(NaN);
|
||||
if (typeof value === 'string') {
|
||||
if (value === '') { return null; } else {
|
||||
const splitted = value.split('/');
|
||||
if (splitted.length !== 3) { return invalidDate; } else {
|
||||
const day = Number(splitted[0]);
|
||||
const month = Number(splitted[1]) - 1;
|
||||
const year = Number(splitted[2]);
|
||||
|
||||
if (day < 1 || day > 31 || month < 0 || month > 11 || year < 1 || year > 9999) { return invalidDate; }
|
||||
|
||||
return new Date(year, month, day);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const dateValue = typeof value === 'number' ? value : Date.parse(value);
|
||||
return isNaN(dateValue) ? invalidDate : new Date(dateValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import {
|
||||
MatToolbarModule,
|
||||
MatIconModule,
|
||||
MatSidenavModule,
|
||||
MatButtonModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatDialogModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatInputModule,
|
||||
MatFormFieldModule,
|
||||
MatSnackBarModule,
|
||||
MatAutocompleteModule,
|
||||
MatExpansionModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatCardModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
DateAdapter,
|
||||
MatTooltipModule,
|
||||
MatTabsModule
|
||||
} from '@angular/material';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { LocalizedDateAdapter } from './date/LocalizedDateAdapter';
|
||||
import { SnackBarNotificationComponent } from 'app/shared/notification/snack-bar-notification.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
MatToolbarModule,
|
||||
MatIconModule,
|
||||
MatSidenavModule,
|
||||
MatButtonModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
CdkTableModule,
|
||||
MatSortModule,
|
||||
MatDialogModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatInputModule,
|
||||
MatFormFieldModule,
|
||||
MatSnackBarModule,
|
||||
MatAutocompleteModule,
|
||||
MatExpansionModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatCardModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule
|
||||
],
|
||||
|
||||
exports: [
|
||||
MatToolbarModule,
|
||||
MatIconModule,
|
||||
MatSidenavModule,
|
||||
MatButtonModule,
|
||||
MatTableModule,
|
||||
MatPaginatorModule,
|
||||
CdkTableModule,
|
||||
MatSortModule,
|
||||
MatDialogModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatInputModule,
|
||||
MatFormFieldModule,
|
||||
MatSnackBarModule,
|
||||
MatAutocompleteModule,
|
||||
MatExpansionModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatCardModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule
|
||||
],
|
||||
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: LocalizedDateAdapter },
|
||||
],
|
||||
|
||||
entryComponents: [
|
||||
SnackBarNotificationComponent
|
||||
]
|
||||
})
|
||||
|
||||
export class MaterialModule {
|
||||
constructor(dateAdapter: DateAdapter<LocalizedDateAdapter>) {
|
||||
dateAdapter.setLocale('el-GR');
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ export class RadioBoxData extends DataField<RadioBoxData>{
|
|||
}
|
||||
|
||||
fromJSONObject(item:any):RadioBoxData{
|
||||
this.options = new JsonSerializer<ListingItem>().fromJSONArray(item.options,ListingItem);
|
||||
this.options = JsonSerializer.fromJSONArray(item.options,ListingItem);
|
||||
this.label = item.label
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export class WordListData extends DataField<WordListData>{
|
|||
|
||||
fromJSONObject(item:any):WordListData{
|
||||
this.type = item.type;
|
||||
this.options = new JsonSerializer<ListingItem>().fromJSONArray(item.options,ListingItem);
|
||||
this.options = JsonSerializer.fromJSONArray(item.options,ListingItem);
|
||||
this.label = item.label;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ export class DatasetProfileModel extends BaseModel implements Serializable<Datas
|
|||
public label: string;
|
||||
|
||||
fromJSONObject(item:any):DatasetProfileModel{
|
||||
this.sections = new JsonSerializer<Section>().fromJSONArray(item.sections, Section);
|
||||
this.pages = new JsonSerializer<Page>().fromJSONArray(item.pages, Page);
|
||||
this.sections = JsonSerializer.fromJSONArray(item.sections, Section);
|
||||
this.pages = JsonSerializer.fromJSONArray(item.pages, Page);
|
||||
this.label = item.label;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -34,23 +34,23 @@ export class Field extends BaseModel implements Serializable<Field>, FormGenerat
|
|||
fromJSONObject(item: any): Field {
|
||||
this.id = item.id;
|
||||
this.title = item.title;
|
||||
this.defaultValue = new JsonSerializer<DefaultValue>().fromJSONObject(item.defaultValue, DefaultValue);
|
||||
this.defaultValue = JsonSerializer.fromJSONObject(item.defaultValue, DefaultValue);
|
||||
this.page = item.page;
|
||||
// this.multiplicity = new JsonSerializer<Multiplicity>().fromJSONObject(item.multiplicity, Multiplicity);
|
||||
this.ordinal = item.ordinal;
|
||||
this.validations = item.validations;
|
||||
this.viewStyle = new JsonSerializer<ViewStyle>().fromJSONObject(item.viewStyle, ViewStyle);
|
||||
this.visible = new JsonSerializer<Visibility>().fromJSONObject(item.visible, Visibility);
|
||||
this.viewStyle = JsonSerializer.fromJSONObject(item.viewStyle, ViewStyle);
|
||||
this.visible = JsonSerializer.fromJSONObject(item.visible, Visibility);
|
||||
if (item.data) {
|
||||
if (this.viewStyle.renderStyle === "combobox") {
|
||||
if (item.data.type === "autocomplete") this.data = new JsonSerializer<AutocompleteData>().fromJSONObject(item.data, AutocompleteData);
|
||||
if (item.data.type === "wordlist") this.data = new JsonSerializer<WordListData>().fromJSONObject(item.data, WordListData);
|
||||
if (item.data.type === "autocomplete") this.data = JsonSerializer.fromJSONObject(item.data, AutocompleteData);
|
||||
if (item.data.type === "wordlist") this.data = JsonSerializer.fromJSONObject(item.data, WordListData);
|
||||
} else {
|
||||
if (this.viewStyle.renderStyle === "radiobox") this.data = new JsonSerializer<RadioBoxData>().fromJSONObject(item.data, RadioBoxData);
|
||||
if (this.viewStyle.renderStyle === "checkBox") this.data = new JsonSerializer<CheckBoxData>().fromJSONObject(item.data, CheckBoxData);
|
||||
if (this.viewStyle.renderStyle === "textarea") this.data = new JsonSerializer<TextArea>().fromJSONObject(item.data, TextArea);
|
||||
if (this.viewStyle.renderStyle === "freetext") this.data = new JsonSerializer<FreeTextData>().fromJSONObject(item.data, FreeTextData);
|
||||
if (this.viewStyle.renderStyle === "booleanDecision") this.data = new JsonSerializer<BooleanDecisionData>().fromJSONObject(item.data, BooleanDecisionData);
|
||||
if (this.viewStyle.renderStyle === "radiobox") this.data = JsonSerializer.fromJSONObject(item.data, RadioBoxData);
|
||||
if (this.viewStyle.renderStyle === "checkBox") this.data = JsonSerializer.fromJSONObject(item.data, CheckBoxData);
|
||||
if (this.viewStyle.renderStyle === "textarea") this.data = JsonSerializer.fromJSONObject(item.data, TextArea);
|
||||
if (this.viewStyle.renderStyle === "freetext") this.data = JsonSerializer.fromJSONObject(item.data, FreeTextData);
|
||||
if (this.viewStyle.renderStyle === "booleanDecision") this.data = JsonSerializer.fromJSONObject(item.data, BooleanDecisionData);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -29,7 +29,7 @@ export class FieldGroup extends BaseModel implements Serializable<FieldGroup>, F
|
|||
this.defaultVisibility = item.defaultVisibility;
|
||||
this.page = item.page;
|
||||
this.ordinal = item.ordinal;
|
||||
this.compositeFields = new JsonSerializer<FieldSet>().fromJSONArray(item.compositeFields, FieldSet);
|
||||
this.compositeFields = JsonSerializer.fromJSONArray(item.compositeFields, FieldSet);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ export class FieldSet extends BaseModel implements Serializable<FieldSet> {
|
|||
|
||||
fromJSONObject(item:any):FieldSet{
|
||||
|
||||
this.fields = new JsonSerializer<Field>().fromJSONArray(item.fields,Field);
|
||||
this.multiplicity = new JsonSerializer<Multiplicity>().fromJSONObject(item.multiplicity, Multiplicity);
|
||||
this.fields = JsonSerializer.fromJSONArray(item.fields,Field);
|
||||
this.multiplicity = JsonSerializer.fromJSONObject(item.multiplicity, Multiplicity);
|
||||
this.id = item.id;
|
||||
this.ordinal = item.ordinal;
|
||||
this.title = item.title;
|
||||
|
|
|
@ -18,7 +18,7 @@ export class Section extends BaseModel implements Serializable<Section>, FormGen
|
|||
public fieldSets: Array<FieldSet> = new Array<FieldSet>();
|
||||
|
||||
fromJSONObject(item: any): Section {
|
||||
this.sections = new JsonSerializer<Section>().fromJSONArray(item.sections, Section);
|
||||
this.sections = JsonSerializer.fromJSONArray(item.sections, Section);
|
||||
//this.fieldGroups = new JsonSerializer<FieldGroup>().fromJSONArray(item.fieldGroups, FieldGroup);
|
||||
this.page = item.page;
|
||||
this.defaultVisibility = item.defaultVisibility;
|
||||
|
@ -26,7 +26,7 @@ export class Section extends BaseModel implements Serializable<Section>, FormGen
|
|||
this.title = item.title;
|
||||
this.description = item.description;
|
||||
this.ordinal = item.ordinal;
|
||||
this.fieldSets = new JsonSerializer<FieldSet>().fromJSONArray(item.fieldSets, FieldSet);
|
||||
this.fieldSets = JsonSerializer.fromJSONArray(item.fieldSets, FieldSet);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ export class Visibility extends BaseModel implements Serializable<Visibility>, F
|
|||
public style:string;
|
||||
|
||||
fromJSONObject(item:any):Visibility{
|
||||
this.rules = new JsonSerializer<Rule>().fromJSONArray(item.rules, Rule);
|
||||
this.rules = JsonSerializer.fromJSONArray(item.rules, Rule);
|
||||
this.style = item.style;
|
||||
|
||||
return this;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export class DataTableData<T> {
|
||||
data = new Array<T>();
|
||||
totalCount = 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { UserCriteria } from '../../core/criteria/UserCriteria';
|
||||
|
||||
export class DataTableRequest {
|
||||
offset = 0;
|
||||
length = 0;
|
||||
userCriteria: UserCriteria;
|
||||
|
||||
constructor(offset: number, length: number) {
|
||||
this.length = length;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* An object used to get page information from the server
|
||||
*/
|
||||
export class Page {
|
||||
// The number of elements in the page
|
||||
size = 0;
|
||||
// The total number of elements
|
||||
totalElements = 0;
|
||||
// The total number of pages
|
||||
totalPages = 0;
|
||||
// The current page number
|
||||
pageNumber = 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { Page } from './page';
|
||||
|
||||
/**
|
||||
* An array of data with an associated page object used for paging
|
||||
*/
|
||||
export class PagedData<T> {
|
||||
data = new Array<T>();
|
||||
page = new Page();
|
||||
}
|
|
@ -43,7 +43,9 @@ const routes: Routes = [
|
|||
component: MainWindowComponent,
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{ path: 'form', loadChildren: './dataset-profile-form/dataset-profile.module#DatasetProfileModule', canActivate: [AuthGuard]}
|
||||
{ path: 'form', loadChildren: './dataset-profile-form/dataset-profile.module#DatasetProfileModule', canActivate: [AuthGuard]},
|
||||
{ path: 'user-management', loadChildren: './users/users.module#UsersModule', canActivate: [AuthGuard]}
|
||||
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Injectable, Inject} from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import {LocalStorageService} from 'ngx-webstorage';
|
||||
import 'rxjs/add/operator/map';
|
||||
import { DOCUMENT } from '@angular/platform-browser';
|
||||
|
||||
|
@ -13,59 +12,59 @@ declare function sign_out_google(): any;
|
|||
export class TokenService {
|
||||
|
||||
|
||||
constructor (private storage : LocalStorageService, @Inject(DOCUMENT) private document) {
|
||||
constructor (@Inject(DOCUMENT) private document) {
|
||||
var csrfToken : string = jQuery(document).find('meta[name="csrf-token"]').attr('content');
|
||||
this.setCSRFToken(csrfToken);
|
||||
}
|
||||
|
||||
|
||||
getCSRFToken() : string{
|
||||
return this.storage.retrieve('csrf-token');
|
||||
return localStorage.retrieve('csrf-token');
|
||||
}
|
||||
|
||||
setCSRFToken(csrfToken : string){
|
||||
this.storage.store('csrf-token',csrfToken);
|
||||
localStorage.store('csrf-token',csrfToken);
|
||||
}
|
||||
|
||||
|
||||
getProvider() : TokenProvider {
|
||||
return this.storage.retrieve('provider');
|
||||
return localStorage.retrieve('provider');
|
||||
}
|
||||
|
||||
setProvider(provider : TokenProvider){
|
||||
this.storage.store('provider',provider);
|
||||
localStorage.store('provider',provider);
|
||||
}
|
||||
|
||||
getToken() : string{
|
||||
return this.storage.retrieve('token');
|
||||
return localStorage.retrieve('token');
|
||||
}
|
||||
|
||||
setToken(token : string){
|
||||
this.storage.store('token',token);
|
||||
localStorage.store('token',token);
|
||||
}
|
||||
|
||||
isLoggedIn(){
|
||||
return this.storage.retrieve('loggedIn');
|
||||
return localStorage.retrieve('loggedIn');
|
||||
}
|
||||
|
||||
setLoggedIn(boolStatus){
|
||||
this.storage.store('loggedIn',boolStatus);
|
||||
localStorage.store('loggedIn',boolStatus);
|
||||
}
|
||||
|
||||
getEmail(){
|
||||
return this.storage.retrieve('email');
|
||||
return localStorage.retrieve('email');
|
||||
}
|
||||
|
||||
setEmail(email){
|
||||
this.storage.store('email',email);
|
||||
localStorage.store('email',email);
|
||||
}
|
||||
|
||||
getUsername(){
|
||||
return this.storage.retrieve('username');
|
||||
return localStorage.retrieve('username');
|
||||
}
|
||||
|
||||
setUsername(username){
|
||||
this.storage.store('username',username);
|
||||
localStorage.store('username',username);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
import { CriteriaErrorModel } from '../models/errormodel/criteriaErrorModel';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormControl, FormGroup, NgForm, FormArray, AbstractControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'base-criteria-component',
|
||||
template: '',
|
||||
providers: [
|
||||
|
||||
]
|
||||
})
|
||||
|
||||
export class BaseCriteriaComponent implements OnInit {
|
||||
|
||||
public refreshCallback: Function = null;
|
||||
public formGroup: FormGroup = null;
|
||||
|
||||
constructor(
|
||||
public baseErrorModel?: CriteriaErrorModel,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.baseErrorModel == null) { this.baseErrorModel = new CriteriaErrorModel(); }
|
||||
}
|
||||
|
||||
controlModified(): void {
|
||||
this.clearErrorModel();
|
||||
if (!this.isFormValid()) { return; }
|
||||
if (this.refreshCallback != null) { this.refreshCallback(); }
|
||||
}
|
||||
|
||||
public isFormValid(): boolean {
|
||||
this.touchAllFormFields(this.formGroup);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
return this.formGroup.valid;
|
||||
}
|
||||
|
||||
public getFormData(): any {
|
||||
return this.formGroup.value;
|
||||
}
|
||||
|
||||
public getFormControl(controlName: string): AbstractControl {
|
||||
return this.formGroup.get(controlName);
|
||||
}
|
||||
|
||||
public disableFormFields(formControl: AbstractControl) {
|
||||
formControl.disable();
|
||||
}
|
||||
|
||||
public validateAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.updateValueAndValidity({ emitEvent: false })
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.validateAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.validateAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public touchAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.markAsTouched();
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.touchAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.touchAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setRefreshCallback(callback: Function): void {
|
||||
this.refreshCallback = callback;
|
||||
}
|
||||
|
||||
onCallbackError(error: any) {
|
||||
this.setErrorModel(error.error);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
}
|
||||
|
||||
public setErrorModel(errorModel: CriteriaErrorModel) {
|
||||
Object.keys(errorModel).forEach(item => {
|
||||
(<any>this.baseErrorModel)[item] = (<any>errorModel)[item];
|
||||
})
|
||||
}
|
||||
|
||||
public clearErrorModel() {
|
||||
Object.keys(this.baseErrorModel).forEach(item => {
|
||||
(<any>this.baseErrorModel)[item] = '';
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export class BaseErrorModel {
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import { BaseErrorModel } from './BaseErrorModel';
|
||||
|
||||
export class CriteriaErrorModel extends BaseErrorModel {
|
||||
public Like: String;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import { CriteriaErrorModel } from '../criteriaErrorModel';
|
||||
|
||||
export class UserCriteriaErrorModel extends CriteriaErrorModel {
|
||||
public Label: String;
|
||||
public Roles: String;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import { BaseErrorModel } from "app/shared/components/criteria/models/errormodel/BaseErrorModel";
|
||||
|
||||
|
||||
export class UserErrorModel extends BaseErrorModel {
|
||||
public Roles: String;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { Serializable } from '../../../../../../models/interfaces/Serializable';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Principal } from 'app/models/login/Principal';
|
||||
|
||||
export class UserListingModel implements Serializable<UserListingModel> {
|
||||
public id: String;
|
||||
public label: String;
|
||||
public roles: Principal.AppRole[];
|
||||
|
||||
fromJSONObject(item: any): UserListingModel {
|
||||
this.id = item.id;
|
||||
this.label = item.label;
|
||||
this.roles = item.roles;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<form class="user-roles-criteria" [formGroup]="formGroup">
|
||||
<mat-card class="mat-card">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-8">
|
||||
<mat-form-field>
|
||||
<input matInput
|
||||
placeholder="{{'CRITERIA.USERS.LABEL'| translate}}"
|
||||
formControlName="label"
|
||||
(ngModelChange)="controlModified()">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="{{'CRITERIA.USERS.ROLE' | translate}}"
|
||||
formControlName="roles"
|
||||
(change)="controlModified()"
|
||||
multiple>
|
||||
<mat-option *ngFor="let role of getPrincipalAppRoleValues()" [value]="role">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
</form>
|
|
@ -0,0 +1,10 @@
|
|||
.user-roles-criteria {
|
||||
mat-form-field {
|
||||
padding-bottom: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Validation, ValidationContext } from '../../../../utilities/validators/ValidationContext';
|
||||
import { UserCriteria } from '../../../../core/criteria/UserCriteria';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BaseCriteriaComponent } from '../base/base-criteria.component';
|
||||
import { Principal } from '../../../../models/login/Principal';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { UserCriteriaErrorModel } from 'app/shared/components/criteria/models/errormodel/users/userCriteriaErrorModel';
|
||||
|
||||
@Component({
|
||||
selector: 'users-criteria-component',
|
||||
templateUrl: './users-criteria.component.html',
|
||||
styleUrls: ['./users-criteria.component.scss'],
|
||||
})
|
||||
|
||||
export class UsersCriteriaComponent extends BaseCriteriaComponent implements OnInit {
|
||||
|
||||
public role: Principal.AppRole;
|
||||
public criteria: UserCriteria = new UserCriteria();
|
||||
|
||||
constructor(
|
||||
public language: TranslateService,
|
||||
public errorModel: UserCriteriaErrorModel,
|
||||
public formBuilder: FormBuilder
|
||||
) {
|
||||
super(errorModel);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
if (this.criteria == null) { this.criteria = new UserCriteria(); }
|
||||
if (this.formGroup == null) { this.formGroup = this.buildForm(); }
|
||||
}
|
||||
|
||||
setCriteria(criteria: UserCriteria): void {
|
||||
this.criteria = criteria;
|
||||
this.formGroup = this.buildForm();
|
||||
}
|
||||
|
||||
public fromJSONObject(item: any): UserCriteria {
|
||||
this.criteria = new UserCriteria();
|
||||
this.criteria.Label = item.Label;
|
||||
this.criteria.Roles = item.Roles;
|
||||
return this.criteria;
|
||||
}
|
||||
|
||||
buildForm(): FormGroup {
|
||||
const context: ValidationContext = this.createValidationContext();
|
||||
|
||||
return this.formBuilder.group({
|
||||
label: [this.criteria.Label, context.getValidation('label').validators],
|
||||
roles: [this.criteria.Roles, context.getValidation('roles').validators],
|
||||
});
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const validationContext: ValidationContext = new ValidationContext();
|
||||
const validationArray: Validation[] = new Array<Validation>();
|
||||
|
||||
validationArray.push({ key: 'label' });
|
||||
validationArray.push({ key: 'roles' });
|
||||
|
||||
validationContext.validation = validationArray;
|
||||
return validationContext;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleValues(): Number[] {
|
||||
let keys: string[] = Object.keys(Principal.AppRole);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleWithLanguage(role: Principal.AppRole): string {
|
||||
let result = '';
|
||||
// this.language.get(new Utilities().convertFromPrincipalAppRole(role)).subscribe((value: string) => {
|
||||
// result = value;
|
||||
// });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_SNACK_BAR_DATA } from '@angular/material';
|
||||
@Component({
|
||||
selector: 'snack-bar-notification',
|
||||
templateUrl: 'snack-bar-notification.html'
|
||||
})
|
||||
|
||||
export class SnackBarNotificationComponent {
|
||||
message: string;
|
||||
constructor( @Inject(MAT_SNACK_BAR_DATA) public data: any) {
|
||||
this.parseMessage(data.message, data.language);
|
||||
}
|
||||
|
||||
parseMessage(message: any, language: TranslateService): void {
|
||||
language.get(message).subscribe((value: string) => {
|
||||
this.message = value;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{{message}}
|
|
@ -0,0 +1,35 @@
|
|||
import { SnackBarNotificationComponent } from './notification/snack-bar-notification.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MaterialModule } from '../material/material.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule } from '../core/core.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
MaterialModule,
|
||||
CoreModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
],
|
||||
|
||||
declarations: [
|
||||
SnackBarNotificationComponent,
|
||||
],
|
||||
|
||||
exports: [
|
||||
SnackBarNotificationComponent,
|
||||
TranslateModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
entryComponents: [
|
||||
]
|
||||
})
|
||||
|
||||
export class SharedModule { }
|
|
@ -1,243 +0,0 @@
|
|||
export const TestModel = {
|
||||
"sections": [
|
||||
{
|
||||
"id": "sumData",
|
||||
"defaultVisibility": "true",
|
||||
"page": "1",
|
||||
"title": "1 Data Summary",
|
||||
"description": " Fill in the fields to describe your data model ",
|
||||
"sections": [],
|
||||
"fieldGroups":
|
||||
[
|
||||
{
|
||||
"id": "dataSummaryGroup",
|
||||
"defaultVisibility": "true",
|
||||
"page": "1",
|
||||
"title": "Data Summary",
|
||||
"description": "",
|
||||
"extendedDescription": "",
|
||||
"compositeFields": [
|
||||
{
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":3
|
||||
},
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "dataSummary",
|
||||
"defaultVisibility": "true",
|
||||
"title": "",
|
||||
"description": "",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "checkBox",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"metadataStandarsA211",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"true",
|
||||
"valueType":"boolean"
|
||||
},
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"freeOfChargeGroupCommentA213",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"true",
|
||||
"valueType":"boolean"
|
||||
},
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"standardisedVocabulariesA212",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"true",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fairData",
|
||||
"ordinal": "2",
|
||||
"defaultVisibility": "true",
|
||||
"page": "1",
|
||||
"title": "2 Fair Data",
|
||||
"sections": [
|
||||
{
|
||||
"id": "dataMetadata",
|
||||
"defaultVisibility": "true",
|
||||
"page": "1",
|
||||
"title": "2.1 Making data findable, including provisions for metadata",
|
||||
"sections": [],
|
||||
"fieldGroups": [
|
||||
{
|
||||
"id": "FindDataMetadataGroup",
|
||||
"section": "dataMetadata",
|
||||
"defaultVisibility": "true",
|
||||
"page": "1",
|
||||
"title": "Making data findable, including provisions for metadata",
|
||||
"description": "Making data findable, including provisions for metadata",
|
||||
"extendedDescription": "FieldGroup Description",
|
||||
"compositeFields": [
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "useMetadataQ211",
|
||||
"defaultVisibility": "true",
|
||||
"title": "Q2.1.1 Will you use metadata to describe the data?",
|
||||
"description": "User can select from a list of metadata standards. If they cannot find the standard in the list provided then they should choose \"not listed\". Selecting this will result in a field in which the user can insert the URL to the description of the metadata scheme used. A \"comments\" box should exist to allow users to add comments. They may select more than one metadata standard. They may specify more than one URL when selecting \"not listed\". They are also presented with a field in which to specify the location of the metadata service. Users can select the \"no metadata\" button to specify no metadata will be used to describe the data.",
|
||||
"extendedDescription": "FieldGroup Description",
|
||||
"viewStyle": "booleanDesicion",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"noMetadata",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"true",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "metadataStandarsA211",
|
||||
"defaultVisibility": "false",
|
||||
"title": "Metadata standards",
|
||||
"description": "The data will be described by metadata that follows the metadata standards described in <url1>, <url2>, ? The data will be described by metadata that follows the metadata schema described in <not-listed-url1>, <not-listed-url2>. The metadata will be stored in the service located at <metadata-repo-url>",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "combobox",
|
||||
"rules":[],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "notlistedA211",
|
||||
"defaultVisibility": "false",
|
||||
"title": "Not listed",
|
||||
"description": "",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "checkBox",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "notlistedUrlA211",
|
||||
"defaultVisibility": "false",
|
||||
"title": "Url",
|
||||
"description": "URL to the description of the metadata scheme used",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "freetext",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "notlistedCommentA211",
|
||||
"defaultVisibility": "false",
|
||||
"title": "Comments",
|
||||
"description": "",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "freetext",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"fields":
|
||||
[
|
||||
{
|
||||
"id": "noMetadata",
|
||||
"defaultVisibility": "false",
|
||||
"title": "The data will not be described by any metadata.",
|
||||
"description": "",
|
||||
"extendedDescription": "",
|
||||
"viewStyle": "checkBox",
|
||||
"rules":[
|
||||
{
|
||||
"ruleType":"fieldValue",
|
||||
"target":"",
|
||||
"ruleStyle":"boolean",
|
||||
"value":"",
|
||||
"valueType":"boolean"
|
||||
}
|
||||
],
|
||||
"multiplicity":{
|
||||
"min":0,
|
||||
"max":1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<form class="user-role-editor" [formGroup]="formGroup" (ngSubmit)="formSubmit()">
|
||||
<mat-form-field class="roles-width-80">
|
||||
<mat-select formControlName="roles"
|
||||
multiple required>
|
||||
<mat-option *ngFor="let role of getPrincipalAppRoleValues()" [value]="role">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="getFormControl('roles').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<button *ngIf="!this.nowEditing" mat-icon-button color="primary" type="button" (click)="editItem()">
|
||||
<mat-icon class="mat-24">edit</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="this.nowEditing" mat-icon-button color="primary" type="submit">
|
||||
<mat-icon class="mat-24">save</mat-icon>
|
||||
</button>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.roles-width-80 {
|
||||
width: 80%;
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
import { UserReferenceService } from '../../../core/services/user-reference-data.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormControl, FormGroup, NgForm, FormArray, AbstractControl, FormBuilder } from '@angular/forms';
|
||||
import { ValidationContext, Validation } from '../../../utilities/validators/ValidationContext';
|
||||
import { Principal } from '../../../models/login/Principal';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { UserListingModel } from 'app/shared/components/criteria/models/errormodel/users/userListingModel';
|
||||
import { UserErrorModel } from 'app/shared/components/criteria/models/errormodel/users/userErrorModel';
|
||||
import { SnackBarNotificationComponent } from 'app/shared/notification/snack-bar-notification.component';
|
||||
|
||||
@Component({
|
||||
selector: 'user-role-editor-component',
|
||||
templateUrl: './user-role-editor.component.html',
|
||||
styleUrls: ['./user-role-editor.component.scss'],
|
||||
providers: [
|
||||
UserReferenceService
|
||||
]
|
||||
})
|
||||
|
||||
export class UserRoleEditorComponent implements OnInit {
|
||||
|
||||
@Input() public item: UserListingModel;
|
||||
private formGroup: FormGroup = null;
|
||||
private nowEditing = false;
|
||||
|
||||
constructor(
|
||||
private language: TranslateService,
|
||||
private userService: UserReferenceService,
|
||||
private errorModel: UserErrorModel,
|
||||
private formBuilder: FormBuilder,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.errorModel == null) { this.errorModel = new UserErrorModel(); }
|
||||
if (this.formGroup == null) { this.formGroup = this.buildForm(); }
|
||||
}
|
||||
|
||||
buildForm(): FormGroup {
|
||||
const context: ValidationContext = this.createValidationContext();
|
||||
|
||||
return this.formBuilder.group({
|
||||
roles: new FormControl({ value: this.item.roles, disabled: true }, context.getValidation('roles').validators)
|
||||
});
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const validationContext: ValidationContext = new ValidationContext();
|
||||
const validationArray: Validation[] = new Array<Validation>();
|
||||
|
||||
validationArray.push({ key: 'roles' });
|
||||
|
||||
validationContext.validation = validationArray;
|
||||
return validationContext;
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.clearErrorModel();
|
||||
|
||||
const modifiedItem = new UserListingModel().fromJSONObject(this.item);
|
||||
modifiedItem.roles = this.getFormControl('roles').value;
|
||||
|
||||
if (!this.isFormValid()) { return; }
|
||||
this.userService.updateRoles(modifiedItem).subscribe(
|
||||
(res) => this.onCallbackSuccess(),
|
||||
(error) => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
|
||||
editItem(): void {
|
||||
this.formGroup.enable();
|
||||
this.nowEditing = true;
|
||||
}
|
||||
|
||||
isFormValid(): boolean {
|
||||
this.touchAllFormFields(this.formGroup);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
return this.formGroup.valid;
|
||||
}
|
||||
|
||||
getFormData(): any {
|
||||
return this.formGroup.value;
|
||||
}
|
||||
|
||||
getFormControl(controlName: string): AbstractControl {
|
||||
return this.formGroup.get(controlName);
|
||||
}
|
||||
|
||||
validateAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.updateValueAndValidity({ emitEvent: false })
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.validateAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.validateAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
touchAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.markAsTouched();
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.touchAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.touchAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setErrorModel(errorModel: UserErrorModel) {
|
||||
Object.keys(errorModel).forEach(item => {
|
||||
(<any>this.errorModel)[item] = (<any>errorModel)[item];
|
||||
})
|
||||
}
|
||||
|
||||
clearErrorModel() {
|
||||
Object.keys(this.errorModel).forEach(item => {
|
||||
(<any>this.errorModel)[item] = '';
|
||||
})
|
||||
}
|
||||
|
||||
onCallbackSuccess() {
|
||||
this.nowEditing = false;
|
||||
this.formGroup.disable();
|
||||
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-success']
|
||||
});
|
||||
}
|
||||
onCallbackError(error: any) {
|
||||
this.setErrorModel(error.error);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE', language: this.language },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-warning']
|
||||
});
|
||||
}
|
||||
|
||||
getPrincipalAppRoleValues(): Number[] {
|
||||
let keys: string[] = Object.keys(Principal.AppRole);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleWithLanguage(role: Principal.AppRole): string {
|
||||
let result = '';
|
||||
/* this.language.get(new Utilities().convertFromPrincipalAppRole(role)).subscribe((value: string) => {
|
||||
result = value;
|
||||
}); */
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<div class="container-fluid">
|
||||
<h3>{{'USERS.LISTING.TITLE' | translate}}</h3>
|
||||
|
||||
<users-criteria-component></users-criteria-component>
|
||||
<mat-card class="mat-card">
|
||||
<mat-progress-bar *ngIf="dataSource?.isLoadingResults" mode="query"></mat-progress-bar>
|
||||
|
||||
<mat-table [dataSource]="dataSource" matSort>
|
||||
|
||||
<!-- Column Definition: Label -->
|
||||
<ng-container cdkColumnDef="label">
|
||||
<mat-header-cell *matHeaderCellDef>{{'USERS.LISTING.LABEL' | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Column Definition: Roles -->
|
||||
<ng-container cdkColumnDef="roles">
|
||||
<mat-header-cell *matHeaderCellDef>{{'USERS.LISTING.ROLES' | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
<user-role-editor-component [item]="row"></user-role-editor-component>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
|
||||
</mat-table>
|
||||
<mat-paginator #paginator
|
||||
[length]="dataSource?.totalCount"
|
||||
[pageSizeOptions]="[10, 25, 100]">
|
||||
</mat-paginator>
|
||||
</mat-card>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
.mat-card {
|
||||
overflow: auto;
|
||||
padding: 0px;
|
||||
|
||||
mat-table {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
mat-progress-bar {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
import { DataTableRequest } from '../../models/data-table/dataTableRequest';
|
||||
import { UserReferenceService } from '../../core/services/user-reference-data.service';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
|
||||
import { UsersCriteriaComponent } from '../../shared/components/criteria/users/users-criteria.component';
|
||||
import { Router } from '@angular/router';
|
||||
import { UserCriteria } from '../../core/criteria/UserCriteria';
|
||||
import { Principal } from '../../models/login/Principal';
|
||||
import { MatPaginator, MatSort, MatSnackBar } from '@angular/material';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DataSource } from '@angular/cdk/table';
|
||||
import { UserListingModel } from 'app/shared/components/criteria/models/errormodel/users/userListingModel';
|
||||
import { SnackBarNotificationComponent } from 'app/shared/notification/snack-bar-notification.component';
|
||||
import { UserCriteriaErrorModel } from 'app/shared/components/criteria/models/errormodel/users/userCriteriaErrorModel';
|
||||
import { UserErrorModel } from 'app/shared/components/criteria/models/errormodel/users/userErrorModel';
|
||||
|
||||
|
||||
export class UsersDataSource extends DataSource<UserListingModel> {
|
||||
|
||||
totalCount = 0;
|
||||
isLoadingResults = false;
|
||||
|
||||
constructor(
|
||||
private _service: UserReferenceService,
|
||||
private _paginator: MatPaginator,
|
||||
private _sort: MatSort,
|
||||
private _languageService: TranslateService,
|
||||
private _snackBar: MatSnackBar,
|
||||
private _criteria: UsersCriteriaComponent
|
||||
) {
|
||||
super();
|
||||
|
||||
//this._paginator.page.subscribe((pageEvent: PageEvent) => {
|
||||
// this.store.dispatch(new LoadPhotosRequestAction(pageEvent.pageIndex, pageEvent.pageSize))
|
||||
//})
|
||||
}
|
||||
|
||||
connect(): Observable<UserListingModel[]> {
|
||||
const displayDataChanges = [
|
||||
this._paginator.page
|
||||
//this._sort.matSortChange
|
||||
];
|
||||
|
||||
// If the user changes the sort order, reset back to the first page.
|
||||
//this._sort.matSortChange.subscribe(() => {
|
||||
// this._paginator.pageIndex = 0;
|
||||
//})
|
||||
|
||||
return Observable.merge(...displayDataChanges)
|
||||
.startWith(null)
|
||||
.switchMap(() => {
|
||||
setTimeout(() => {
|
||||
this.isLoadingResults = true;
|
||||
});
|
||||
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
|
||||
const request = new DataTableRequest(startIndex, this._paginator.pageSize);
|
||||
request.userCriteria = this._criteria.getFormData();
|
||||
return this._service.getPaged(request);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
this._snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-warning']
|
||||
});
|
||||
this._criteria.onCallbackError(error);
|
||||
return Observable.of(null);
|
||||
})
|
||||
.map(result => {
|
||||
setTimeout(() => {
|
||||
this.isLoadingResults = false;
|
||||
});
|
||||
return result;
|
||||
})
|
||||
.map(result => {
|
||||
if (!result) { return []; }
|
||||
if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
|
||||
//result.data.forEach((element: any) => {
|
||||
// const roles: String[] = [];
|
||||
// element.roles.forEach((role: any) => {
|
||||
// this._languageService.get(this._utilities.convertFromPrincipalAppRole(role)).subscribe(
|
||||
// value => roles.push(value)
|
||||
// );
|
||||
// });
|
||||
// element.roles = roles;
|
||||
//});
|
||||
return result.data;
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-users-component',
|
||||
templateUrl: './users.component.html',
|
||||
styleUrls: ['./users.component.scss'],
|
||||
providers: [
|
||||
UserReferenceService,
|
||||
UserCriteriaErrorModel,
|
||||
UserErrorModel
|
||||
],
|
||||
})
|
||||
export class UsersComponent implements OnInit, AfterViewInit {
|
||||
|
||||
@ViewChild(MatPaginator) _paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
@ViewChild(UsersCriteriaComponent) criteria: UsersCriteriaComponent;
|
||||
|
||||
dataSource: UsersDataSource | null;
|
||||
displayedColumns: String[] = ['label', 'roles'];
|
||||
|
||||
constructor(private userService: UserReferenceService, private router: Router, private languageService: TranslateService, public snackBar: MatSnackBar) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
//this.refresh(); //called on ngAfterViewInit with default criteria
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.criteria.setRefreshCallback(() => this.refresh());
|
||||
this.criteria.setCriteria(this.getDefaultCriteria());
|
||||
this.criteria.controlModified();
|
||||
});
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.dataSource = new UsersDataSource(this.userService, this._paginator, this.sort, this.languageService, this.snackBar, this.criteria, );
|
||||
}
|
||||
|
||||
getDefaultCriteria(): UserCriteria {
|
||||
const defaultCriteria = new UserCriteria();
|
||||
return defaultCriteria;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import { UsersCriteriaComponent } from '../shared/components/criteria/users/users-criteria.component';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { UsersComponent } from './components/users.component';
|
||||
import { UsersRoutes } from './users.routes';
|
||||
import { MaterialModule } from '../material/material.module';
|
||||
import { UserRoleEditorComponent } from './components/roles/user-role-editor.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
UsersRoutes,
|
||||
SharedModule,
|
||||
MaterialModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
UsersComponent,
|
||||
UsersCriteriaComponent,
|
||||
UserRoleEditorComponent
|
||||
],
|
||||
|
||||
exports: [
|
||||
UsersComponent
|
||||
]
|
||||
})
|
||||
|
||||
export class UsersModule { }
|
|
@ -0,0 +1,8 @@
|
|||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { UsersComponent } from './components/users.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'users', component: UsersComponent }
|
||||
];
|
||||
|
||||
export const UsersRoutes = RouterModule.forChild(routes);
|
|
@ -0,0 +1,25 @@
|
|||
import { MyHttpService } from './myhttpservice.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { MaterialModule } from '../../material/material.module';
|
||||
import { CoreModule } from '../../core/core.module';
|
||||
import { AuthService } from 'app/services/auth/auth.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MaterialModule,
|
||||
CoreModule.forRoot()
|
||||
]
|
||||
})
|
||||
export class MyHttpModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: MyHttpModule,
|
||||
providers: [
|
||||
AuthService,
|
||||
MyHttpService
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Http, RequestOptions, Response, Headers } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Router, ActivatedRoute, RouterStateSnapshot } from '@angular/router';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { AuthService } from 'app/services/auth/auth.service';
|
||||
import { SnackBarNotificationComponent } from 'app/shared/notification/snack-bar-notification.component';
|
||||
|
||||
@Injectable()
|
||||
export class MyHttpService {
|
||||
constructor(
|
||||
protected http: HttpClient,
|
||||
private router: Router,
|
||||
private authService: AuthService,
|
||||
public language: TranslateService,
|
||||
public snackBar: MatSnackBar,
|
||||
|
||||
) {
|
||||
}
|
||||
get<T>(url: string, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.get(url, this.buildRequestOptions(options)));
|
||||
}
|
||||
post<T>(url: string, body: any, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.post(url, body, this.buildRequestOptions(options)));
|
||||
}
|
||||
put<T>(url: string, body: any, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.put(url, body, this.buildRequestOptions(options)));
|
||||
}
|
||||
delete<T>(url: string, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.delete(url, this.buildRequestOptions(options)));
|
||||
}
|
||||
patch<T>(url: string, body: any, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse(this.http.patch(url, body, this.buildRequestOptions(options)));
|
||||
}
|
||||
head<T>(url: string, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.head(url, this.buildRequestOptions(options)));
|
||||
}
|
||||
options<T>(url: string, options?: any): Observable<T> {
|
||||
return this.interceptRepsonse<T>(this.http.options(url, this.buildRequestOptions(options)));
|
||||
}
|
||||
|
||||
protected buildRequestOptions(options?: any): Object {
|
||||
if (options == null) {
|
||||
options = new RequestOptions();
|
||||
}
|
||||
if (options.headers == null) {
|
||||
options.headers = new Headers();
|
||||
}
|
||||
if (!options.headers.has('Content-Type')) {
|
||||
options.headers = options.headers.set('Content-Type', 'application/json');
|
||||
}
|
||||
if (!options.headers.has('Content-Type')) {
|
||||
options.headers = options.headers.set('Content-Type', 'application/json');
|
||||
}
|
||||
if (!options.headers.has('AuthToken')) {
|
||||
const principal = this.authService.current();
|
||||
if (principal) {
|
||||
options.headers = options.headers.set('AuthToken', principal.token);
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private interceptRepsonse<T>(observable: Observable<Object>): Observable<T> {
|
||||
return observable
|
||||
.catch((error) => {
|
||||
if (error.status === 401) {
|
||||
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT', language: this.language },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-success']
|
||||
})
|
||||
this.router.navigate(['/unauthorized']);
|
||||
//this.notification.httpError(error);
|
||||
return Observable.of<T>();
|
||||
} else {
|
||||
return Observable.throw(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { ValidatorFn, AbstractControl } from '@angular/forms';
|
||||
import { BaseErrorModel } from 'app/shared/components/criteria/models/errormodel/BaseErrorModel';
|
||||
|
||||
export function BackendErrorValidator(errorModel: BaseErrorModel, propertyName: string): ValidatorFn {
|
||||
return (control: AbstractControl): { [key: string]: any } => {
|
||||
const error: string = (<any>errorModel)[propertyName];
|
||||
return error ? { 'backendError': { value: error } } : null;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { ValidatorFn } from '@angular/forms';
|
||||
|
||||
export class ValidationContext {
|
||||
validation: Validation[];
|
||||
|
||||
getValidation(key: string): Validation {
|
||||
for (let i = 0; i < this.validation.length; i++) {
|
||||
if (this.validation[i].key === key) {
|
||||
return this.validation[i];
|
||||
}
|
||||
}
|
||||
throw new Error('Key Was Not Found In The Validation Context');
|
||||
}
|
||||
}
|
||||
|
||||
export class Validation {
|
||||
key: string;
|
||||
validators?: ValidatorFn[] = new Array<ValidatorFn>();
|
||||
descendantValidations?: ValidationContext;
|
||||
}
|
|
@ -26,6 +26,7 @@ import static eu.eudat.types.Authorities.USER;
|
|||
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
@RequestMapping(value = "user")
|
||||
public class Users extends BaseController {
|
||||
|
||||
@Autowired
|
||||
|
@ -33,7 +34,7 @@ public class Users extends BaseController {
|
|||
super(apiContext);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/users/getPaged"}, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json")
|
||||
public @ResponseBody
|
||||
ResponseEntity<ResponseItem<DataTableData<UserListingModel>>> getPaged(@Valid @RequestBody UserInfoTableRequestItem userInfoTableRequestItem, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
|
||||
try {
|
||||
|
@ -46,9 +47,9 @@ public class Users extends BaseController {
|
|||
}
|
||||
|
||||
@Transactional
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/users/editRoles"}, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/updateRoles"}, consumes = "application/json", produces = "application/json")
|
||||
public @ResponseBody
|
||||
ResponseEntity<ResponseItem<UserListingModel>> editRoles(@Valid @RequestBody UserListingModel userListingModel, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
|
||||
ResponseEntity<ResponseItem<UserListingModel>> updateRoles(@Valid @RequestBody UserListingModel userListingModel, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
|
||||
try {
|
||||
UserManager.editRoles(this.getApiContext(), userListingModel);
|
||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UserListingModel>().status(ApiMessageCode.NO_MESSAGE));
|
||||
|
|
|
@ -5,4 +5,6 @@ public interface DatabaseAccessLayer<T, I> {
|
|||
T createOrUpdate(T item);
|
||||
|
||||
T find(I id);
|
||||
|
||||
void delete(T item);
|
||||
}
|
||||
|
|
|
@ -60,4 +60,9 @@ public class DMPDaoImpl extends DatabaseAccess<DMP> implements DMPDao {
|
|||
public Long count() {
|
||||
return this.getDatabaseService().count(DMP.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(DMP item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class DataRepositoryDaoImpl extends DatabaseAccess<DataRepository> implem
|
|||
public DataRepository createOrUpdate(DataRepository item) {
|
||||
return getDatabaseService().createOrUpdate(item, DataRepository.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(DataRepository item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,4 +51,9 @@ public class DatasetDaoImpl extends DatabaseAccess<Dataset> implements DatasetDa
|
|||
public Long count() {
|
||||
return this.getDatabaseService().count(Dataset.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Dataset item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess<DatasetProfile> implem
|
|||
public QueryableList<DatasetProfile> getAll() {
|
||||
return getDatabaseService().getQueryable(DatasetProfile.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(DatasetProfile item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class ExternalDatasetDaoImpl extends DatabaseAccess<ExternalDataset> impl
|
|||
public ExternalDataset find(UUID id) {
|
||||
return this.getDatabaseService().getQueryable(ExternalDataset.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(ExternalDataset item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,4 +35,8 @@ public class InvitationDaoImpl extends DatabaseAccess<Invitation> implements Inv
|
|||
return this.getDatabaseService().getQueryable(Invitation.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Invitation item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,9 @@ public class OrganisationDaoImpl extends DatabaseAccess<Organisation> implements
|
|||
public Organisation find(UUID id) {
|
||||
return this.getDatabaseService().getQueryable(Organisation.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Organisation item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,9 @@ public class ProjectDaoImpl extends DatabaseAccess<Project> implements ProjectDa
|
|||
public Long count() {
|
||||
return this.getDatabaseService().count(Project.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Project item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class RegistryDaoImpl extends DatabaseAccess<Registry> implements Registr
|
|||
public Registry find(UUID id) {
|
||||
return this.getDatabaseService().getQueryable(Registry.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Registry item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class ResearcherDaoImpl extends DatabaseAccess<Researcher> implements Res
|
|||
public Researcher find(UUID id) {
|
||||
return this.getDatabaseService().getQueryable(Researcher.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Researcher item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class ServiceDaoImpl extends DatabaseAccess<Service> implements ServiceDa
|
|||
public Service find(UUID id) {
|
||||
return this.getDatabaseService().getQueryable(Service.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Service item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,8 @@ public class UserInfoDaoImpl extends DatabaseAccess<UserInfo> implements UserInf
|
|||
return this.getDatabaseService().getQueryable(UserInfo.class).where((builder, root) -> builder.equal(root.get("id"),id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(UserInfo item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
|
@ -34,4 +34,9 @@ public class UserRoleDaoImpl extends DatabaseAccess<UserRole> implements UserRo
|
|||
public List<UserRole> getUserRoles(UserInfo userInfo) {
|
||||
return this.getDatabaseService().getQueryable(UserRole.class).where((builder, root) -> builder.equal(root.get("userInfo"),userInfo)).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(UserRole item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,9 @@ public class CredentialDaoImpl extends DatabaseAccess<Credential> implements Cre
|
|||
builder.equal(root.get("provider"), TokenValidatorFactoryImpl.LoginProvider.NATIVELOGIN.getValue())
|
||||
))).getSingleOrDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Credential item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,7 @@ public class UserInfo implements DataEntity<UserInfo>{
|
|||
this.email = entity.getEmail();
|
||||
this.additionalinfo = entity.getAdditionalinfo();
|
||||
this.lastloggedin = entity.getLastloggedin();
|
||||
this.userRoles = entity.getUserRoles();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,8 +47,7 @@ public class UserManager {
|
|||
|
||||
public static void editRoles(ApiContext apiContext, UserListingModel user) {
|
||||
eu.eudat.entities.UserInfo userInfo = apiContext.getDatabaseRepository().getUserInfoDao().find(user.getId());
|
||||
userInfo.getUserRoles().removeAll(userInfo.getUserRoles());
|
||||
userInfo = apiContext.getDatabaseRepository().getUserInfoDao().createOrUpdate(userInfo);
|
||||
userInfo.getUserRoles().stream().forEach(item -> apiContext.getDatabaseRepository().getUserRoleDao().delete(item));
|
||||
for (Integer role : user.getAppRoles()) {
|
||||
UserRole userRole = new UserRole();
|
||||
userRole.setRole(role);
|
||||
|
|
|
@ -104,6 +104,7 @@ public class UserListingModel implements DataModel<eu.eudat.entities.UserInfo> {
|
|||
|
||||
@Override
|
||||
public void fromDataModel(UserInfo entity) throws InstantiationException, IllegalAccessException {
|
||||
this.id = entity.getId();
|
||||
this.email = entity.getEmail();
|
||||
this.usertype = entity.getUsertype();
|
||||
this.verified_email = entity.getVerified_email();
|
||||
|
|
|
@ -12,8 +12,8 @@ const appRoutes: Routes = [
|
|||
{ path: "dmps", loadChildren: './dmps/dmps.module#DataManagementPlanModule',canActivate: [AuthGuard] },
|
||||
{ path: 'welcome', component: HomepageComponent, canActivate: [AuthGuard] },
|
||||
{ path: '', redirectTo: '/welcome', pathMatch: 'full' },
|
||||
{ path: "unauthorized", loadChildren: './unauthorized/unauthorized.module#UnauthorizedModule' }
|
||||
|
||||
{ path: "unauthorized", loadChildren: './unauthorized/unauthorized.module#UnauthorizedModule' },
|
||||
{ path: "users", loadChildren: './users/users.module#UsersModule' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { BaseCriteria } from '../BaseCriteria';
|
||||
import { Principal } from "@app/models/login/Principal";
|
||||
|
||||
|
||||
|
||||
export class UserCriteria extends BaseCriteria {
|
||||
public Label: String;
|
||||
public Roles: Principal.AppRole[];
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import { BaseCriteriaErrorModel } from '../BaseCriteriaErrorModel';
|
||||
|
||||
export class UserCriteriaErrorModel extends BaseCriteriaErrorModel {
|
||||
public Label: String;
|
||||
public Roles: String;
|
||||
}
|
|
@ -20,7 +20,8 @@ export class Principal implements Serializable<Principal> {
|
|||
|
||||
export namespace Principal {
|
||||
export enum AppRole {
|
||||
Admin = 0,
|
||||
User = 1
|
||||
Manager = 2,
|
||||
Admin = 1,
|
||||
User = 0,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { BaseErrorModel } from "@app/models/error/BaseErrorModel";
|
||||
|
||||
|
||||
export class UserErrorModel extends BaseErrorModel {
|
||||
public Roles: String;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { Serializable } from '../Serializable';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Principal } from 'app/models/login/Principal';
|
||||
|
||||
export class UserListingModel implements Serializable<UserListingModel> {
|
||||
public id: String;
|
||||
public name: String;
|
||||
public appRoles: Principal.AppRole[];
|
||||
|
||||
fromJSONObject(item: any): UserListingModel {
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
this.appRoles = item.appRoles;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import { UserListingModel } from '../../models/users/UserListingModel';
|
||||
import { UserCriteria } from '../../models/criteria/users/UserCriteria';
|
||||
import { BaseHttpService } from '../../utilities/cite-http-service-module/base-http.service';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { DataTableRequest } from '../../models/data-table/dataTableRequest';
|
||||
import { DataTableData } from '../../models/data-table/dataTableData';
|
||||
import { HostConfiguration } from 'app/app.constants';
|
||||
|
||||
@Injectable()
|
||||
export class UserReferenceService {
|
||||
|
||||
private actionUrl: string;
|
||||
private headers: HttpHeaders;
|
||||
|
||||
constructor(private http: BaseHttpService) {
|
||||
|
||||
this.actionUrl = HostConfiguration.Server + '/user/';
|
||||
|
||||
this.headers = new HttpHeaders();
|
||||
this.headers = this.headers.set('Content-Type', 'application/json');
|
||||
this.headers = this.headers.set('Accept', 'application/json');
|
||||
}
|
||||
|
||||
// formatItem(utilities: Utilities, item: ConfigurationModel): ConfigurationModel {
|
||||
// item.validFrom = new Date(item.validFrom);
|
||||
// item.validTo = new Date(item.validTo);
|
||||
// return item
|
||||
// }
|
||||
|
||||
getPaged(dataTableRequest: DataTableRequest<UserCriteria>): Observable<DataTableData<UserListingModel>> {
|
||||
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
|
||||
}
|
||||
|
||||
updateRoles(itemToUpdate: UserListingModel): Observable<UserListingModel> {
|
||||
return this.http.post<UserListingModel>(this.actionUrl + 'updateRoles', JSON.stringify(itemToUpdate), { headers: this.headers });
|
||||
}
|
||||
|
||||
delete(id: String): Observable<any> {
|
||||
return this.http.delete<any>(this.actionUrl + id, { headers: this.headers });
|
||||
}
|
||||
}
|
|
@ -13,19 +13,80 @@ import { BaseCriteriaErrorModel } from '../../../../models/criteria/BaseCriteria
|
|||
export class BaseCriteriaComponent implements OnInit {
|
||||
|
||||
public refreshCallback: Function = null;
|
||||
public baseErrorModel: BaseCriteriaErrorModel = new BaseCriteriaErrorModel();
|
||||
public formGroup: FormGroup = null;
|
||||
|
||||
constructor(baseErrorModel: BaseCriteriaErrorModel) {
|
||||
this.baseErrorModel = baseErrorModel;
|
||||
constructor(
|
||||
public baseErrorModel?: BaseCriteriaErrorModel,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.baseErrorModel == null) { this.baseErrorModel = new BaseCriteriaErrorModel(); }
|
||||
}
|
||||
|
||||
controlModified(): void {
|
||||
this.clearErrorModel();
|
||||
if (!this.isFormValid()) { return; }
|
||||
if (this.refreshCallback != null) { this.refreshCallback(); }
|
||||
}
|
||||
|
||||
public isFormValid(): boolean {
|
||||
this.touchAllFormFields(this.formGroup);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
return this.formGroup.valid;
|
||||
}
|
||||
|
||||
public getFormData(): any {
|
||||
return this.formGroup.value;
|
||||
}
|
||||
|
||||
public getFormControl(controlName: string): AbstractControl {
|
||||
return this.formGroup.get(controlName);
|
||||
}
|
||||
|
||||
public disableFormFields(formControl: AbstractControl) {
|
||||
formControl.disable();
|
||||
}
|
||||
|
||||
public validateAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.updateValueAndValidity({ emitEvent: false })
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.validateAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.validateAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public touchAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.markAsTouched();
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.touchAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.touchAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setRefreshCallback(callback: Function): void {
|
||||
this.refreshCallback = callback;
|
||||
}
|
||||
|
||||
onCallbackError(error: any) {
|
||||
this.setErrorModel(error.error);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
}
|
||||
|
||||
public setErrorModel(errorModel: BaseCriteriaErrorModel) {
|
||||
Object.keys(errorModel).forEach(item => {
|
||||
(<any>this.baseErrorModel)[item] = (<any>errorModel)[item];
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<form class="user-roles-criteria" [formGroup]="formGroup">
|
||||
<mat-card class="mat-card">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-8">
|
||||
<mat-form-field>
|
||||
<input matInput
|
||||
placeholder="{{'CRITERIA.USERS.LABEL'| translate}}"
|
||||
formControlName="label"
|
||||
(ngModelChange)="controlModified()">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="{{'CRITERIA.USERS.ROLE' | translate}}"
|
||||
formControlName="roles"
|
||||
(change)="controlModified()"
|
||||
multiple>
|
||||
<mat-option *ngFor="let role of getPrincipalAppRoleValues()" [value]="role">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
</form>
|
|
@ -0,0 +1,10 @@
|
|||
.user-roles-criteria {
|
||||
mat-form-field {
|
||||
padding-bottom: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
import { Utilities } from '../../../../utilities/utilities';
|
||||
import { UserCriteriaErrorModel } from '../../../../models/criteria/users/UserCriteriaErrorModel';
|
||||
import { UserCriteria } from '../../../../models/criteria/users/UserCriteria';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Validation, ValidationContext } from '../../../../utilities/validators/ValidationContext';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BaseCriteriaComponent } from '../base/base-criteria.component';
|
||||
import { Principal } from '../../../../models/login/Principal';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'users-criteria-component',
|
||||
templateUrl: './users-criteria.component.html',
|
||||
styleUrls: ['./users-criteria.component.scss'],
|
||||
})
|
||||
|
||||
export class UsersCriteriaComponent extends BaseCriteriaComponent implements OnInit {
|
||||
|
||||
public role: Principal.AppRole;
|
||||
public criteria: UserCriteria = new UserCriteria();
|
||||
|
||||
constructor(
|
||||
public language: TranslateService,
|
||||
public errorModel: UserCriteriaErrorModel,
|
||||
public formBuilder: FormBuilder
|
||||
) {
|
||||
super(errorModel);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
if (this.criteria == null) { this.criteria = new UserCriteria(); }
|
||||
if (this.formGroup == null) { this.formGroup = this.buildForm(); }
|
||||
}
|
||||
|
||||
setCriteria(criteria: UserCriteria): void {
|
||||
this.criteria = criteria;
|
||||
this.formGroup = this.buildForm();
|
||||
}
|
||||
|
||||
public fromJSONObject(item: any): UserCriteria {
|
||||
this.criteria = new UserCriteria();
|
||||
this.criteria.Label = item.Label;
|
||||
this.criteria.Roles = item.Roles;
|
||||
return this.criteria;
|
||||
}
|
||||
|
||||
buildForm(): FormGroup {
|
||||
const context: ValidationContext = this.createValidationContext();
|
||||
|
||||
return this.formBuilder.group({
|
||||
label: [this.criteria.Label, context.getValidation('label').validators],
|
||||
roles: [this.criteria.Roles, context.getValidation('roles').validators],
|
||||
});
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const validationContext: ValidationContext = new ValidationContext();
|
||||
const validationArray: Validation[] = new Array<Validation>();
|
||||
|
||||
validationArray.push({ key: 'label' });
|
||||
validationArray.push({ key: 'roles' });
|
||||
|
||||
validationContext.validation = validationArray;
|
||||
return validationContext;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleValues(): Number[] {
|
||||
let keys: string[] = Object.keys(Principal.AppRole);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleWithLanguage(role: Principal.AppRole): string {
|
||||
let result = '';
|
||||
this.language.get(new Utilities().convertFromPrincipalAppRole(role)).subscribe((value: string) => {
|
||||
result = value;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<form class="user-role-editor" [formGroup]="formGroup" (ngSubmit)="formSubmit()">
|
||||
<mat-form-field class="roles-width-80">
|
||||
<mat-select formControlName="appRoles"
|
||||
multiple required>
|
||||
<mat-option *ngFor="let role of getPrincipalAppRoleValues()" [value]="role">{{getPrincipalAppRoleWithLanguage(role)}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="getFormControl('appRoles').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<button *ngIf="!this.nowEditing" mat-icon-button color="primary" type="button" (click)="editItem()">
|
||||
<mat-icon class="mat-24">edit</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="this.nowEditing" mat-icon-button color="primary" type="submit">
|
||||
<mat-icon class="mat-24">save</mat-icon>
|
||||
</button>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.roles-width-80 {
|
||||
width: 80%;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
import { Utilities } from '../../../utilities/utilities';
|
||||
import { UserErrorModel } from '../../../models/users/UserErrorModel';
|
||||
import { UserListingModel } from '../../../models/users/UserListingModel';
|
||||
import { UserReferenceService } from '../../../services/user-reference/user-reference-data.service';
|
||||
import { SnackBarNotificationComponent } from '../../../shared/components/notificaiton/snack-bar-notification.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { FormControl, FormGroup, NgForm, FormArray, AbstractControl, FormBuilder } from '@angular/forms';
|
||||
import { ValidationContext, Validation } from '../../../utilities/validators/ValidationContext';
|
||||
import { Principal } from '../../../models/login/Principal';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'user-role-editor-component',
|
||||
templateUrl: './user-role-editor.component.html',
|
||||
styleUrls: ['./user-role-editor.component.scss'],
|
||||
providers: [
|
||||
UserReferenceService
|
||||
]
|
||||
})
|
||||
|
||||
export class UserRoleEditorComponent implements OnInit {
|
||||
|
||||
@Input() public item: UserListingModel;
|
||||
private formGroup: FormGroup = null;
|
||||
private nowEditing = false;
|
||||
|
||||
constructor(
|
||||
private language: TranslateService,
|
||||
private userService: UserReferenceService,
|
||||
private errorModel: UserErrorModel,
|
||||
private formBuilder: FormBuilder,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.errorModel == null) { this.errorModel = new UserErrorModel(); }
|
||||
if (this.formGroup == null) { this.formGroup = this.buildForm(); }
|
||||
}
|
||||
|
||||
buildForm(): FormGroup {
|
||||
const context: ValidationContext = this.createValidationContext();
|
||||
|
||||
return this.formBuilder.group({
|
||||
appRoles: new FormControl({ value: this.item.appRoles, disabled: true }, context.getValidation('appRoles').validators)
|
||||
});
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const validationContext: ValidationContext = new ValidationContext();
|
||||
const validationArray: Validation[] = new Array<Validation>();
|
||||
|
||||
validationArray.push({ key: 'appRoles' });
|
||||
|
||||
validationContext.validation = validationArray;
|
||||
return validationContext;
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.clearErrorModel();
|
||||
|
||||
const modifiedItem = new UserListingModel().fromJSONObject(this.item);
|
||||
modifiedItem.appRoles = this.getFormControl('appRoles').value;
|
||||
|
||||
if (!this.isFormValid()) { return; }
|
||||
this.userService.updateRoles(modifiedItem).subscribe(
|
||||
(res) => this.onCallbackSuccess(),
|
||||
(error) => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
|
||||
editItem(): void {
|
||||
this.formGroup.enable();
|
||||
this.nowEditing = true;
|
||||
}
|
||||
|
||||
isFormValid(): boolean {
|
||||
this.touchAllFormFields(this.formGroup);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
return this.formGroup.valid;
|
||||
}
|
||||
|
||||
getFormData(): any {
|
||||
return this.formGroup.value;
|
||||
}
|
||||
|
||||
getFormControl(controlName: string): AbstractControl {
|
||||
return this.formGroup.get(controlName);
|
||||
}
|
||||
|
||||
validateAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.updateValueAndValidity({ emitEvent: false })
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.validateAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.validateAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
touchAllFormFields(formControl: AbstractControl) {
|
||||
if (formControl instanceof FormControl) {
|
||||
formControl.markAsTouched();
|
||||
} else if (formControl instanceof FormGroup) {
|
||||
Object.keys(formControl.controls).forEach(item => {
|
||||
const control = formControl.get(item);
|
||||
this.touchAllFormFields(control);
|
||||
})
|
||||
} else if (formControl instanceof FormArray) {
|
||||
formControl.controls.forEach(item => {
|
||||
this.touchAllFormFields(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setErrorModel(errorModel: UserErrorModel) {
|
||||
Object.keys(errorModel).forEach(item => {
|
||||
(<any>this.errorModel)[item] = (<any>errorModel)[item];
|
||||
})
|
||||
}
|
||||
|
||||
clearErrorModel() {
|
||||
Object.keys(this.errorModel).forEach(item => {
|
||||
(<any>this.errorModel)[item] = '';
|
||||
})
|
||||
}
|
||||
|
||||
onCallbackSuccess() {
|
||||
this.nowEditing = false;
|
||||
this.formGroup.disable();
|
||||
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-success']
|
||||
});
|
||||
}
|
||||
onCallbackError(error: any) {
|
||||
this.setErrorModel(error.error);
|
||||
this.validateAllFormFields(this.formGroup);
|
||||
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE', language: this.language },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-warning']
|
||||
});
|
||||
}
|
||||
|
||||
getPrincipalAppRoleValues(): Number[] {
|
||||
let keys: string[] = Object.keys(Principal.AppRole);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getPrincipalAppRoleWithLanguage(role: Principal.AppRole): string {
|
||||
let result = '';
|
||||
this.language.get(new Utilities().convertFromPrincipalAppRole(role)).subscribe((value: string) => {
|
||||
result = value;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<div class="container-fluid">
|
||||
<h3>{{'USERS.LISTING.TITLE' | translate}}</h3>
|
||||
|
||||
<users-criteria-component></users-criteria-component>
|
||||
<mat-card class="mat-card">
|
||||
<mat-progress-bar *ngIf="dataSource?.isLoadingResults" mode="query"></mat-progress-bar>
|
||||
|
||||
<mat-table [dataSource]="dataSource" matSort>
|
||||
|
||||
<!-- Column Definition: Label -->
|
||||
<ng-container cdkColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef>{{'USERS.LISTING.LABEL' | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Column Definition: Roles -->
|
||||
<ng-container cdkColumnDef="roles">
|
||||
<mat-header-cell *matHeaderCellDef>{{'USERS.LISTING.ROLES' | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
<user-role-editor-component [item]="row"></user-role-editor-component>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
|
||||
</mat-table>
|
||||
<mat-paginator #paginator
|
||||
[length]="dataSource?.totalCount"
|
||||
[pageSizeOptions]="[10, 25, 100]">
|
||||
</mat-paginator>
|
||||
</mat-card>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
.mat-card {
|
||||
overflow: auto;
|
||||
padding: 0px;
|
||||
|
||||
mat-table {
|
||||
margin: 24px;
|
||||
}
|
||||
|
||||
mat-progress-bar {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
import { DataTableRequest } from '../../models/data-table/DataTableRequest';
|
||||
import { UserErrorModel } from '../../models/users/UserErrorModel';
|
||||
import { UserReferenceService } from '../../services/user-reference/user-reference-data.service';
|
||||
import { UserListingModel } from '../../models/users/UserListingModel';
|
||||
import { SnackBarNotificationComponent } from '../../shared/components/notificaiton/snack-bar-notification.component';
|
||||
import { UserCriteria } from '../../models/criteria/users/UserCriteria';
|
||||
import { UserCriteriaErrorModel } from '../../models/criteria/users/UserCriteriaErrorModel';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
|
||||
import { UsersCriteriaComponent } from '../../shared/components/criteria/users/users-criteria.component';
|
||||
import { Router } from '@angular/router';
|
||||
import { Principal } from '../../models/login/Principal';
|
||||
import { MatPaginator, MatSort, MatSnackBar } from '@angular/material';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DataSource } from '@angular/cdk/table';
|
||||
|
||||
|
||||
export class UsersDataSource extends DataSource<UserListingModel> {
|
||||
|
||||
totalCount = 0;
|
||||
isLoadingResults = false;
|
||||
|
||||
constructor(
|
||||
private _service: UserReferenceService,
|
||||
private _paginator: MatPaginator,
|
||||
private _sort: MatSort,
|
||||
private _languageService: TranslateService,
|
||||
private _snackBar: MatSnackBar,
|
||||
private _criteria: UsersCriteriaComponent
|
||||
) {
|
||||
super();
|
||||
|
||||
//this._paginator.page.subscribe((pageEvent: PageEvent) => {
|
||||
// this.store.dispatch(new LoadPhotosRequestAction(pageEvent.pageIndex, pageEvent.pageSize))
|
||||
//})
|
||||
}
|
||||
|
||||
connect(): Observable<UserListingModel[]> {
|
||||
const displayDataChanges = [
|
||||
this._paginator.page
|
||||
//this._sort.matSortChange
|
||||
];
|
||||
|
||||
// If the user changes the sort order, reset back to the first page.
|
||||
//this._sort.matSortChange.subscribe(() => {
|
||||
// this._paginator.pageIndex = 0;
|
||||
//})
|
||||
|
||||
return Observable.merge(...displayDataChanges)
|
||||
.startWith(null)
|
||||
.switchMap(() => {
|
||||
setTimeout(() => {
|
||||
this.isLoadingResults = true;
|
||||
});
|
||||
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
|
||||
const request = new DataTableRequest<UserCriteria>(startIndex, this._paginator.pageSize);
|
||||
request.criteria = this._criteria.getFormData();
|
||||
return this._service.getPaged(request);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
this._snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
|
||||
duration: 3000,
|
||||
extraClasses: ['snackbar-warning']
|
||||
});
|
||||
this._criteria.onCallbackError(error);
|
||||
return Observable.of(null);
|
||||
})
|
||||
.map(result => {
|
||||
setTimeout(() => {
|
||||
this.isLoadingResults = false;
|
||||
});
|
||||
return result;
|
||||
})
|
||||
.map(result => {
|
||||
if (!result) { return []; }
|
||||
if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
|
||||
//result.data.forEach((element: any) => {
|
||||
// const roles: String[] = [];
|
||||
// element.roles.forEach((role: any) => {
|
||||
// this._languageService.get(this._utilities.convertFromPrincipalAppRole(role)).subscribe(
|
||||
// value => roles.push(value)
|
||||
// );
|
||||
// });
|
||||
// element.roles = roles;
|
||||
//});
|
||||
return result.data;
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-users-component',
|
||||
templateUrl: './users.component.html',
|
||||
styleUrls: ['./users.component.scss'],
|
||||
providers: [
|
||||
UserReferenceService,
|
||||
UserCriteriaErrorModel,
|
||||
UserErrorModel
|
||||
],
|
||||
})
|
||||
export class UsersComponent implements OnInit, AfterViewInit {
|
||||
|
||||
@ViewChild(MatPaginator) _paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
@ViewChild(UsersCriteriaComponent) criteria: UsersCriteriaComponent;
|
||||
|
||||
dataSource: UsersDataSource | null;
|
||||
displayedColumns: String[] = ['name', 'roles'];
|
||||
|
||||
constructor(private userService: UserReferenceService, private router: Router, private languageService: TranslateService, public snackBar: MatSnackBar) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
//this.refresh(); //called on ngAfterViewInit with default criteria
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.criteria.setRefreshCallback(() => this.refresh());
|
||||
this.criteria.setCriteria(this.getDefaultCriteria());
|
||||
this.criteria.controlModified();
|
||||
});
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.dataSource = new UsersDataSource(this.userService, this._paginator, this.sort, this.languageService, this.snackBar, this.criteria, );
|
||||
}
|
||||
|
||||
getDefaultCriteria(): UserCriteria {
|
||||
const defaultCriteria = new UserCriteria();
|
||||
return defaultCriteria;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { UsersCriteriaComponent } from '../shared/components/criteria/users/users-criteria.component';
|
||||
import { MaterialModule } from '../shared/material/material.module';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { UsersComponent } from './components/users.component';
|
||||
import { UsersRoutes } from './users.routes';
|
||||
import { UserRoleEditorComponent } from './components/roles/user-role-editor.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
UsersRoutes,
|
||||
SharedModule,
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
ReactiveFormsModule,
|
||||
MaterialModule
|
||||
],
|
||||
|
||||
declarations: [
|
||||
UsersComponent,
|
||||
UsersCriteriaComponent,
|
||||
UserRoleEditorComponent
|
||||
],
|
||||
|
||||
exports: [
|
||||
UsersComponent
|
||||
]
|
||||
})
|
||||
|
||||
export class UsersModule {
|
||||
constructor(private translate: TranslateService) {
|
||||
translate.setDefaultLang('en');
|
||||
translate.use('en');
|
||||
}
|
||||
}
|
||||
|
||||
export function HttpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, 'assets/lang/', '.json');
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { UsersComponent } from './components/users.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: UsersComponent }
|
||||
];
|
||||
|
||||
export const UsersRoutes = RouterModule.forChild(routes);
|
|
@ -0,0 +1,15 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder, FormArray, FormGroup } from '@angular/forms';
|
||||
import { Principal } from '../models/login/Principal';
|
||||
|
||||
@Injectable()
|
||||
export class Utilities {
|
||||
|
||||
convertFromPrincipalAppRole(status: Principal.AppRole): string {
|
||||
switch (status) {
|
||||
case Principal.AppRole.Admin: return 'TYPES.APP-ROLE.ADMIN'
|
||||
case Principal.AppRole.User: return 'TYPES.APP-ROLE.USER'
|
||||
case Principal.AppRole.Manager: return 'TYPES.APP-ROLE.MANAGER'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -149,6 +149,10 @@
|
|||
"DMP": {
|
||||
"LIKE": "Search",
|
||||
"PROJECTS": "Projects"
|
||||
},
|
||||
"USERS": {
|
||||
"LABEL": "Label",
|
||||
"ROLE": "Role"
|
||||
}
|
||||
},
|
||||
"DATASET-EDITOR": {
|
||||
|
@ -179,5 +183,19 @@
|
|||
"SEND-INVITATION": "Send Invitations",
|
||||
"CANCEL": "Cancel"
|
||||
}
|
||||
},
|
||||
"USERS": {
|
||||
"LISTING": {
|
||||
"TITLE": "Users",
|
||||
"LABEL": "Label",
|
||||
"ROLES": "Roles"
|
||||
}
|
||||
},
|
||||
"TYPES": {
|
||||
"APP-ROLE": {
|
||||
"ADMIN": "Admin",
|
||||
"USER": "User",
|
||||
"MANAGER": "Manager"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue