styling changes

*user-profile
This commit is contained in:
Sofia Papacharalampous 2024-03-19 17:12:36 +02:00
parent 5f52e646a5
commit 551249af33
5 changed files with 81 additions and 69 deletions

View File

@ -412,19 +412,6 @@
</property> </property>
</activation> </activation>
</profile> </profile>
<profile>
<id>cite-dev</id>
<repositories>
<repository>
<id>cite-maven</id>
<name>CITE Maven Repository</name>
<url>https://crepo.cite.gr/repository/cite-maven/</url>
</repository>
</repositories>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles> </profiles>
</project> </project>

View File

@ -62,6 +62,12 @@ export interface UserCredential {
externalId: String; externalId: String;
user: User; user: User;
createdAt: Date; createdAt: Date;
data: UserCredentialData
}
export interface UserCredentialData {
externalProviderNames: String[];
email: String;
} }
export interface DmpAssociatedUser { export interface DmpAssociatedUser {

View File

@ -3,7 +3,7 @@
<h1 mat-dialog-title class="title">{{'USER-PROFILE.ACTIONS.LINK-NEW-ACCOUNT' | translate}}</h1> <h1 mat-dialog-title class="title">{{'USER-PROFILE.ACTIONS.LINK-NEW-ACCOUNT' | translate}}</h1>
<span class="ml-auto align-self-center" (click)="closeDialog()"><mat-icon class="close-icon">close</mat-icon></span> <span class="ml-auto align-self-center" (click)="closeDialog()"><mat-icon class="close-icon">close</mat-icon></span>
</div> </div>
<app-login *ngIf="hasEmail" [mergeUsers]="true" redirect="false"></app-login> <!-- <app-login *ngIf="hasEmail" [mergeUsers]="true" redirect="false"></app-login> -->
<div *ngIf="!hasEmail"> <div *ngIf="!hasEmail">
<div mat-dialog-content class="definition-content pt-2"> <div mat-dialog-content class="definition-content pt-2">
<mat-form-field class="full-width"> <mat-form-field class="full-width">

View File

@ -1,3 +1,5 @@
<!-- {{ userCredentials | async | json }} -->
<div class="profile"> <div class="profile">
<div class="container-fluid"> <div class="container-fluid">
<div *ngIf="user | async as userProfile; else loading" class="user-profile"> <div *ngIf="user | async as userProfile; else loading" class="user-profile">
@ -30,7 +32,7 @@
</div> </div>
<!-- Accounts --> <!-- Accounts -->
<!-- TODO: How to present these. --> <!-- TODO: How to present these. -->
<!-- <div class="row mb-5"> <div class="row mb-5">
<div class="col"> <div class="col">
<div class="row"> <div class="row">
<div class="col-auto field-title">{{'USER-PROFILE.SETTINGS.ACCOUNTS' | translate}}</div> <div class="col-auto field-title">{{'USER-PROFILE.SETTINGS.ACCOUNTS' | translate}}</div>
@ -41,20 +43,24 @@
</div> </div>
<div class="col-auto vertical-line"> <div class="col-auto vertical-line">
<div *ngIf="userCredentials"> <div *ngIf="userCredentials">
<div *ngFor="let userCredential of userCredentials; index as i"> <div *ngFor="let userCredential of userCredentials | async; index as i">
<div class="row user-credential"> <div class="row user-credential" *ngIf="userCredential.data">
<div class="col-auto mail-text pr-0">{{userCredential.email}}</div> <div class="col-auto mail-text pr-0">{{userCredential.data.email}}</div>
<span *ngIf="userCredential.provider === authProviderEnum.Google" class="googleIcon"></span> <span *ngIf="hasProvider(userCredential, 'Google')" class="googleIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.Facebook" class="facebookIcon"></span> <span *ngIf="hasProvider(userCredential, 'Facebook')" class="facebookIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.Twitter" class="twitterIcon"></span> <!-- <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.Twitter)" class="twitterIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.LinkedIn" class="linkedInIcon"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.LinkedIn)" class="linkedInIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.B2Access" class="b2AccessIcon"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.B2Access)" class="b2AccessIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.ORCID" class="orcidIconMedium"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.ORCID)" class="orcidIconMedium"></span>
<span *ngIf="userCredential.provider === authProviderEnum.OpenAire" class="openaireIcon"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.OpenAire)" class="openaireIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.Configurable" class="configurableIcon"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.Configurable)" class="configurableIcon"></span>
<span *ngIf="userCredential.provider === authProviderEnum.Zenodo" class="zenodoIcon"></span> <span *ngIf="hasProvider(userCredential.data.provider, authProviderEnum.Zenodo)" class="zenodoIcon"></span> -->
<div *ngIf="i != 0" class="col-auto d-flex align-items-center unlink-mail" (click)="userCredential.email !== userCredentials[0].email && removeAccount(userCredential)"> <div *ngIf="i != 0" class="col-auto d-flex align-items-center unlink-mail" (click)="userCredential.data.email !== firstEmail && removeAccount(userCredential)">
<mat-icon [matTooltip]="(userCredential.email !== userCredentials[0].email) ? ('USER-PROFILE.ACTIONS.UNLINK-ACCOUNT' | translate) : ('USER-PROFILE.ACTIONS.UNLINK-ACCOUNT-DISABLED' | translate)" matTooltipPosition="right" [ngClass]="{'disable-unlink':userCredential.email === userCredentials[0].email}">link_off</mat-icon> <mat-icon
[matTooltip]="(userCredential.data?.email !== firstEmail ) ? ('USER-PROFILE.ACTIONS.UNLINK-ACCOUNT' | translate) : ('USER-PROFILE.ACTIONS.UNLINK-ACCOUNT-DISABLED' | translate)"
matTooltipPosition="right"
[ngClass]="{'disable-unlink':userCredential.data.email === firstEmail}"
>link_off</mat-icon>
</div> </div>
</div> </div>
</div> </div>
@ -68,31 +74,29 @@
</div> </div>
</div> </div>
</div> </div>
</div> --> </div>
<!-- Organization --> <!-- Organization -->
<div class="row mb-5"> <div class="row mb-5">
<div class="col"> <div class="col-6">
<div class="row"> <div class="row">
<div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.ORGANIZATION' | translate}}</div> <div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.ORGANIZATION' | translate}}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col organization-form"> <div class="col organization-form">
<mat-form-field> <mat-form-field class="w-100">
<app-single-auto-complete placeholder="{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}" [formControl]="this.formGroup.get('organization')" [configuration]="organisationsAutoCompleteConfiguration"></app-single-auto-complete> <app-single-auto-complete placeholder="{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}" [formControl]="this.formGroup.get('organization')" [configuration]="organisationsAutoCompleteConfiguration"></app-single-auto-complete>
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
</div> </div>
</div> <!-- Role -->
<!-- Role --> <div class="col-6">
<div class="row mb-5">
<div class="col">
<div class="row"> <div class="row">
<div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.ROLE' | translate}}</div> <div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.ROLE' | translate}}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col role-form"> <div class="col role-form">
<mat-form-field> <mat-form-field class="w-100">
<mat-select placeholder="{{'USER-PROFILE.SETTINGS.SELECT-ROLE' | translate}}" [formControl]="this.formGroup.get('roleOrganization')"> <mat-select placeholder="{{'USER-PROFILE.SETTINGS.SELECT-ROLE' | translate}}" [formControl]="this.formGroup.get('roleOrganization')">
<mat-option [value]="roleOrganizationEnum.Faculty">{{enumUtils.toRoleOrganizationString(roleOrganizationEnum.Faculty)}}</mat-option> <mat-option [value]="roleOrganizationEnum.Faculty">{{enumUtils.toRoleOrganizationString(roleOrganizationEnum.Faculty)}}</mat-option>
<mat-option [value]="roleOrganizationEnum.Librarian">{{enumUtils.toRoleOrganizationString(roleOrganizationEnum.Librarian)}}</mat-option> <mat-option [value]="roleOrganizationEnum.Librarian">{{enumUtils.toRoleOrganizationString(roleOrganizationEnum.Librarian)}}</mat-option>
@ -116,13 +120,13 @@
</div> </div>
<!-- Timezone --> <!-- Timezone -->
<div class="row mb-5"> <div class="row mb-5">
<div class="col"> <div class="col-4">
<div class="row"> <div class="row">
<div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}} *</div> <div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}} *</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col timezone-form"> <div class="col timezone-form">
<mat-form-field> <mat-form-field class="w-100">
<input type="text" placeholder="{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}}" [formControl]="this.formGroup.get('timezone')" matInput [matAutocomplete]="timezone" required> <input type="text" placeholder="{{'USER-PROFILE.SETTINGS.TIMEZONE' | translate}}" [formControl]="this.formGroup.get('timezone')" matInput [matAutocomplete]="timezone" required>
<mat-autocomplete #timezone="matAutocomplete"> <mat-autocomplete #timezone="matAutocomplete">
<mat-option *ngFor="let timezone of timezones | async" [value]="timezone"> <mat-option *ngFor="let timezone of timezones | async" [value]="timezone">
@ -134,16 +138,14 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Culture --> <!-- Culture -->
<div class="row mb-5"> <div class="col-4">
<div class="col">
<div class="row"> <div class="row">
<div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.CULTURE' | translate}} *</div> <div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.CULTURE' | translate}} *</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col culture-form"> <div class="col culture-form">
<mat-form-field> <mat-form-field class="w-100">
<input type="text" placeholder="{{'USER-PROFILE.SETTINGS.CULTURE' | translate}}" [formControl]="this.formGroup.get('culture')" matInput [matAutocomplete]="culture" required> <input type="text" placeholder="{{'USER-PROFILE.SETTINGS.CULTURE' | translate}}" [formControl]="this.formGroup.get('culture')" matInput [matAutocomplete]="culture" required>
<mat-autocomplete #culture="matAutocomplete" [displayWith]="displayFn"> <mat-autocomplete #culture="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let culture of cultures | async" [value]="culture"> <mat-option *ngFor="let culture of cultures | async" [value]="culture">
@ -155,17 +157,15 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Language --> <!-- Language -->
<div class="row mb-5"> <div class="col-4">
<div class="col">
<div class="row"> <div class="row">
<div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}} *</div> <div class="col-auto mb-1 field-title">{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}} *</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col language-form"> <div class="col language-form">
<mat-form-field> <mat-form-field class="w-100">
<!-- <mat-label>{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}}</mat-label> --> <!-- <mat-label>{{'USER-PROFILE.SETTINGS.LANGUAGE' | translate}}</mat-label> -->
<mat-select [formControl]="this.formGroup.get('language')" name="language"> <mat-select [formControl]="this.formGroup.get('language')" name="language">
<mat-option *ngFor="let language of languages" [value]="language"> <mat-option *ngFor="let language of languages" [value]="language">

View File

@ -6,7 +6,7 @@ import { ActivatedRoute, Params, Router } from '@angular/router';
import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type'; import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type';
import { CultureInfo } from '@app/core/model/culture-info'; import { CultureInfo } from '@app/core/model/culture-info';
import { Reference } from '@app/core/model/reference/reference'; import { Reference } from '@app/core/model/reference/reference';
import { User } from '@app/core/model/user/user'; import { User, UserCredential } from '@app/core/model/user/user';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { CultureService } from '@app/core/services/culture/culture-service'; import { CultureService } from '@app/core/services/culture/culture-service';
@ -39,7 +39,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
userProfileEditorModel: UserProfileEditorModel; userProfileEditorModel: UserProfileEditorModel;
user: Observable<User>; user: Observable<User>;
//TODO: refactor //TODO: refactor
// userCredentials: UserCredentialModel[]; userCredentials: Observable<UserCredential[]>;
firstEmail: String;
currentUserId: string; currentUserId: string;
cultures: Observable<CultureInfo[]>; cultures: Observable<CultureInfo[]>;
timezones: Observable<any[]>; timezones: Observable<any[]>;
@ -95,31 +96,42 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
nameof<User>(x => x.additionalInfo.culture), nameof<User>(x => x.additionalInfo.culture),
nameof<User>(x => x.additionalInfo.organization), nameof<User>(x => x.additionalInfo.organization),
nameof<User>(x => x.additionalInfo.roleOrganization), nameof<User>(x => x.additionalInfo.roleOrganization),
`${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.email)}`,
`${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.externalProviderNames)}`,
] ]
) )
.pipe(map(result => { .pipe(map(result => {
//result['additionalinfo'] = JSON.parse(result['additionalinfo']); //tested ui with fake data
// const fakecredentials: UserCredential = {
// "id": Guid.createEmpty(),
// "externalId": "123",
// "user": null,
// "createdAt": new Date(),
// "data": {
// "email": "dmpadmin@dmp.com",
// "externalProviderNames": ["Google", "Facebook"]
// }
// };
// result.credentials.push(fakecredentials);
// result.credentials[0].data.externalProviderNames = ['Google'];
this.firstEmail = result.credentials[0].data.email;
this.userCredentials = of(result.credentials);
this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result); this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result);
this.formGroup = this.userProfileEditorModel.buildForm(this.languageService.getAvailableLanguagesCodes()); this.formGroup = this.userProfileEditorModel.buildForm(this.languageService.getAvailableLanguagesCodes());
// this.formGroup = new FormBuilder().group({ //this.formGroup.get('language').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { if (x) this.translate.use(x.value) })
// language: new FormControl(result['language'] ? availableLanguages.filter(x => x.value === result['language']['value']).pop() : '', [Validators.required]), this.formGroup.get('timezone').valueChanges
// timezone: new FormControl(result['timezone'], [Validators.required]), .pipe(takeUntil(this._destroyed))
// culture: new FormControl(result['culture'], [Validators.required]) .subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } });
// }); this.formGroup.get('culture').valueChanges
.pipe(takeUntil(this._destroyed))
//this.formGroup.get('language').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { if (x) this.translate.use(x.value) }) .subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } });
this.formGroup.get('timezone').valueChanges // this.initializeDisabledFormGroup();
.pipe(takeUntil(this._destroyed)) this.unlock();
.subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } }); return result;
this.formGroup.get('culture').valueChanges }));
.pipe(takeUntil(this._destroyed))
.subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } });
// this.initializeDisabledFormGroup();
this.unlock();
return result;
}));
//TODO: refactor //TODO: refactor
// this.userService.getEmails(userId).pipe(takeUntil(this._destroyed)) // this.userService.getEmails(userId).pipe(takeUntil(this._destroyed))
@ -138,6 +150,12 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
ngOnDestroy(): void { ngOnDestroy(): void {
} }
public hasProvider(userCredential: UserCredential, provider: string): boolean {
const result = userCredential.data.externalProviderNames?.find(x => x == provider);
return result != null;
}
private filterOrganisations(value: string): Observable<Reference[]> { private filterOrganisations(value: string): Observable<Reference[]> {
//TODO: refactor //TODO: refactor
// return this.externalSourcesService.searchDMPOrganizations(value); // return this.externalSourcesService.searchDMPOrganizations(value);
@ -259,6 +277,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
.subscribe(confirm => { .subscribe(confirm => {
if (confirm) { if (confirm) {
//TODO: refactor //TODO: refactor
console.log('removed!');
// const unlinkAccountModel: UnlinkAccountRequestModel = { // const unlinkAccountModel: UnlinkAccountRequestModel = {
// userId: this.currentUserId, // userId: this.currentUserId,
// email: userCredential.email, // email: userCredential.email,