diff --git a/apps/red-ui/src/app/app-routing.module.ts b/apps/red-ui/src/app/app-routing.module.ts index 016bece60..5989691a8 100644 --- a/apps/red-ui/src/app/app-routing.module.ts +++ b/apps/red-ui/src/app/app-routing.module.ts @@ -7,7 +7,6 @@ import { RouteReuseStrategy, RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component'; import { AppStateGuard } from '@state/app-state.guard'; -import { UserProfileScreenComponent } from '@components/user-profile/user-profile-screen.component'; import { CustomRouteReuseStrategy } from '@utils/custom-route-reuse.strategy'; const routes = [ @@ -22,18 +21,9 @@ const routes = [ canActivate: [AuthGuard] }, { - path: 'main/my-profile', + path: 'main/account', component: BaseScreenComponent, - children: [ - { - path: '', - component: UserProfileScreenComponent - } - ], - canActivate: [CompositeRouteGuard], - data: { - routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard] - } + loadChildren: () => import('./modules/account/account.module').then(m => m.AccountModule) }, { path: 'main/admin', diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index c55cb1263..c5e8f9cd6 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -23,7 +23,6 @@ import { DownloadsListScreenComponent } from '@components/downloads-list-screen/ import { AppRoutingModule } from './app-routing.module'; import { SharedModule } from '@shared/shared.module'; import { FileUploadDownloadModule } from '@upload-download/file-upload-download.module'; -import { UserProfileScreenComponent } from '@components/user-profile/user-profile-screen.component'; import { PlatformLocation } from '@angular/common'; import { BASE_HREF } from './tokens'; import { MONACO_PATH, MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; @@ -53,7 +52,7 @@ function cleanupBaseUrl(baseUrl: string) { } } -const screens = [BaseScreenComponent, DownloadsListScreenComponent, UserProfileScreenComponent]; +const screens = [BaseScreenComponent, DownloadsListScreenComponent]; const components = [ AppComponent, diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts index aa8b2cd4b..e834bc426 100644 --- a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts +++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts @@ -37,9 +37,10 @@ export class BaseScreenComponent { readonly isSearchScreen$ = this._navigationStart$.pipe(map(isSearchScreen)); readonly userMenuItems: readonly MenuItem[] = [ { - name: _('top-bar.navigation-items.my-account.children.my-profile'), - routerLink: '/main/my-profile', - show: true + name: _('top-bar.navigation-items.my-account.children.account'), + routerLink: '/main/account', + show: true, + action: this.appStateService.reset }, { name: _('top-bar.navigation-items.my-account.children.admin'), diff --git a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.html b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.html index a2b00defe..322dd97b4 100644 --- a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.html +++ b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.html @@ -1,50 +1,50 @@ -
-
-
-
-
-
-
-
-
-
-
- - -
+ + + + + + + + + + + + + + -
- - -
+ + + + -
- - -
-
- - - - {{ translations[language] | translate }} - - -
-
-
+ + + + + + + + + + + + + + -
- - {{ 'user-profile.actions.change-password' | translate }} -
-
-
-
-
+ + + + + + + + + + + + + + + diff --git a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.scss b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.scss index 677b2c3d2..118317781 100644 --- a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.scss +++ b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.scss @@ -1,27 +1,27 @@ -@use 'variables'; -@use 'common-mixins'; - -.content-container { - background-color: variables.$grey-2; - justify-content: center; - @include common-mixins.scroll-bar; - overflow: auto; -} - -.full-height { - display: flex; - flex-direction: row; - position: absolute; - bottom: 0; - width: 100%; - height: calc(100% + 50px); - z-index: 1; -} - -iframe { - background: white; - width: 500px; - height: 500px; - position: absolute; - z-index: 100; -} +//@use 'variables'; +//@use 'common-mixins'; +// +//.content-container { +// background-color: variables.$grey-2; +// justify-content: center; +// @include common-mixins.scroll-bar; +// overflow: auto; +//} +// +//.full-height { +// display: flex; +// flex-direction: row; +// position: absolute; +// bottom: 0; +// width: 100%; +// height: calc(100% + 50px); +// z-index: 1; +//} +// +//iframe { +// background: white; +// width: 500px; +// height: 500px; +// position: absolute; +// z-index: 100; +//} diff --git a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts index ef48662d2..47714ed5f 100644 --- a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts +++ b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts @@ -1,116 +1,116 @@ -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { ProfileModel, UserService } from '@services/user.service'; -import { PermissionsService } from '@services/permissions.service'; -import { LanguageService } from '@i18n/language.service'; -import { TranslateService } from '@ngx-translate/core'; -import { UserControllerService } from '@redaction/red-ui-http'; -import { ConfigService } from '@services/config.service'; -import { DomSanitizer } from '@angular/platform-browser'; -import { languagesTranslations } from '../../translations/languages-translations'; -import { LoadingService } from '@iqser/common-ui'; - -@Component({ - selector: 'redaction-user-profile-screen', - templateUrl: './user-profile-screen.component.html', - styleUrls: ['./user-profile-screen.component.scss'] -}) -export class UserProfileScreenComponent implements OnInit { - formGroup: FormGroup; - changePasswordUrl: any; - translations = languagesTranslations; - - private _profileModel: ProfileModel; - - constructor( - readonly permissionsService: PermissionsService, - private readonly _formBuilder: FormBuilder, - private readonly _userService: UserService, - private readonly _configService: ConfigService, - private readonly _userControllerService: UserControllerService, - private readonly _languageService: LanguageService, - private readonly _domSanitizer: DomSanitizer, - private readonly _translateService: TranslateService, - private readonly _loadingService: LoadingService - ) { - this._loadingService.start(); - this.formGroup = this._formBuilder.group({ - email: [undefined, [Validators.required, Validators.email]], - firstName: [undefined], - lastName: [undefined], - language: [undefined] - }); - - this.changePasswordUrl = this._domSanitizer.bypassSecurityTrustResourceUrl( - this._configService.values.OAUTH_URL + '/account/password' - ); - } - - get languageChanged(): boolean { - return this._profileModel['language'] !== this.formGroup.get('language').value; - } - - get profileChanged(): boolean { - const keys = Object.keys(this.formGroup.getRawValue()); - keys.splice(keys.indexOf('language'), 1); - - for (const key of keys) { - if (this._profileModel[key] !== this.formGroup.get(key).value) { - return true; - } - } - - return false; - } - - get languages(): string[] { - return this._translateService.langs; - } - - ngOnInit() { - this._initializeForm(); - } - - async save(): Promise { - this._loadingService.start(); - - if (this.languageChanged) { - await this._languageService.changeLanguage(this.formGroup.get('language').value); - } - - if (this.profileChanged) { - const value = this.formGroup.value as ProfileModel; - delete value.language; - - await this._userControllerService - .updateMyProfile({ - ...value - }) - .toPromise(); - - await this._userService.loadCurrentUser(); - await this._userService.loadAllUsers(); - } - - this._initializeForm(); - } - - private _initializeForm(): void { - try { - this._profileModel = { - email: this._userService.currentUser.email, - firstName: this._userService.currentUser.firstName, - lastName: this._userService.currentUser.lastName, - language: this._languageService.currentLanguage - }; - if (this._userService.currentUser.email) { - // disable email if it's already set - this.formGroup.get('email').disable(); - } - this.formGroup.patchValue(this._profileModel, { emitEvent: false }); - } catch (e) { - } finally { - this._loadingService.stop(); - } - } -} +// import { Component, OnInit } from '@angular/core'; +// import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +// import { ProfileModel, UserService } from '@services/user.service'; +// import { PermissionsService } from '@services/permissions.service'; +// import { LanguageService } from '@i18n/language.service'; +// import { TranslateService } from '@ngx-translate/core'; +// import { UserControllerService } from '@redaction/red-ui-http'; +// import { ConfigService } from '@services/config.service'; +// import { DomSanitizer } from '@angular/platform-browser'; +// import { languagesTranslations } from '../../translations/languages-translations'; +// import { LoadingService } from '@iqser/common-ui'; +// +// @Component({ +// selector: 'redaction-user-profile-screen', +// templateUrl: './user-profile-screen.component.html', +// styleUrls: ['./user-profile-screen.component.scss'] +// }) +// export class UserProfileScreenComponent implements OnInit { +// formGroup: FormGroup; +// changePasswordUrl: any; +// translations = languagesTranslations; +// +// private _profileModel: ProfileModel; +// +// constructor( +// readonly permissionsService: PermissionsService, +// private readonly _formBuilder: FormBuilder, +// private readonly _userService: UserService, +// private readonly _configService: ConfigService, +// private readonly _userControllerService: UserControllerService, +// private readonly _languageService: LanguageService, +// private readonly _domSanitizer: DomSanitizer, +// private readonly _translateService: TranslateService, +// private readonly _loadingService: LoadingService +// ) { +// this._loadingService.start(); +// this.formGroup = this._formBuilder.group({ +// email: [undefined, [Validators.required, Validators.email]], +// firstName: [undefined], +// lastName: [undefined], +// language: [undefined] +// }); +// +// this.changePasswordUrl = this._domSanitizer.bypassSecurityTrustResourceUrl( +// this._configService.values.OAUTH_URL + '/account/password' +// ); +// } +// +// get languageChanged(): boolean { +// return this._profileModel['language'] !== this.formGroup.get('language').value; +// } +// +// get profileChanged(): boolean { +// const keys = Object.keys(this.formGroup.getRawValue()); +// keys.splice(keys.indexOf('language'), 1); +// +// for (const key of keys) { +// if (this._profileModel[key] !== this.formGroup.get(key).value) { +// return true; +// } +// } +// +// return false; +// } +// +// get languages(): string[] { +// return this._translateService.langs; +// } +// +// ngOnInit() { +// this._initializeForm(); +// } +// +// async save(): Promise { +// this._loadingService.start(); +// +// if (this.languageChanged) { +// await this._languageService.changeLanguage(this.formGroup.get('language').value); +// } +// +// if (this.profileChanged) { +// const value = this.formGroup.value as ProfileModel; +// delete value.language; +// +// await this._userControllerService +// .updateMyProfile({ +// ...value +// }) +// .toPromise(); +// +// await this._userService.loadCurrentUser(); +// await this._userService.loadAllUsers(); +// } +// +// this._initializeForm(); +// } +// +// private _initializeForm(): void { +// try { +// this._profileModel = { +// email: this._userService.currentUser.email, +// firstName: this._userService.currentUser.firstName, +// lastName: this._userService.currentUser.lastName, +// language: this._languageService.currentLanguage +// }; +// if (this._userService.currentUser.email) { +// // disable email if it's already set +// this.formGroup.get('email').disable(); +// } +// this.formGroup.patchValue(this._profileModel, { emitEvent: false }); +// } catch (e) { +// } finally { +// this._loadingService.stop(); +// } +// } +// } diff --git a/apps/red-ui/src/app/modules/account/account-routing.module.ts b/apps/red-ui/src/app/modules/account/account-routing.module.ts new file mode 100644 index 000000000..31d95beb4 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/account-routing.module.ts @@ -0,0 +1,35 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { CompositeRouteGuard } from '../../guards/composite-route.guard'; +import { AuthGuard } from '../auth/auth.guard'; +import { RedRoleGuard } from '../auth/red-role.guard'; +import { AppStateGuard } from '../../state/app-state.guard'; +import { NotificationsScreenComponent } from './screens/notifications/notifications.component'; +import { UserProfileScreenComponent } from './screens/user-profile/user-profile.component'; + +const routes = [ + { path: '', redirectTo: 'user-profile', pathMatch: 'full' }, + { + path: 'user-profile', + component: UserProfileScreenComponent, + canActivate: [CompositeRouteGuard], + data: { + routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard], + requiredRoles: ['RED_USER'] + } + }, + { + path: 'notifications', + component: NotificationsScreenComponent, + canActivate: [CompositeRouteGuard], + data: { + routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard] + } + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class AccountRoutingModule {} diff --git a/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.html b/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.html new file mode 100644 index 000000000..791992dc9 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.html @@ -0,0 +1,7 @@ + + +
+ {{ item.label | translate }} +
+
+
diff --git a/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.scss b/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.ts b/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.ts new file mode 100644 index 000000000..8c3986e10 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/account-side-nav/account-side-nav.component.ts @@ -0,0 +1,27 @@ +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { Component } from '@angular/core'; + +interface NavItem { + readonly label: string; + readonly screen: string; +} + +@Component({ + selector: 'redaction-account-side-nav', + templateUrl: './account-side-nav.component.html', + styleUrls: ['./account-side-nav.component.scss'] +}) +export class AccountSideNavComponent { + readonly items: NavItem[] = [ + { + screen: 'user-profile', + label: _('user-profile') + }, + { + screen: 'notifications', + label: _('notifications') + } + ]; + + constructor() {} +} diff --git a/apps/red-ui/src/app/modules/account/account.module.ts b/apps/red-ui/src/app/modules/account/account.module.ts new file mode 100644 index 000000000..ab03c0314 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/account.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '../shared/shared.module'; +import { AccountRoutingModule } from './account-routing.module'; +import { AccountSideNavComponent } from './account-side-nav/account-side-nav.component'; +import { NotificationsScreenComponent } from './screens/notifications/notifications.component'; +import { UserProfileScreenComponent } from './screens/user-profile/user-profile.component'; + +const screens = [NotificationsScreenComponent, UserProfileScreenComponent]; + +const components = [AccountSideNavComponent, ...screens]; + +@NgModule({ + declarations: [components], + providers: [], + imports: [CommonModule, SharedModule, AccountRoutingModule] +}) +export class AccountModule {} diff --git a/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.html b/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.html new file mode 100644 index 000000000..1d07a02f3 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.html @@ -0,0 +1,34 @@ +
+
+ + + +
+ +
+
+ + + + + + + + +
+
+
+
diff --git a/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.scss b/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.ts b/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.ts new file mode 100644 index 000000000..586e58537 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/notifications/notifications.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'redaction-notifications-screen', + templateUrl: './notifications.component.html', + styleUrls: ['./notifications.component.scss'] +}) +export class NotificationsScreenComponent {} diff --git a/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.html b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.html new file mode 100644 index 000000000..8a19b4a78 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.html @@ -0,0 +1,14 @@ +
+
+ + + +
+ +
+
+
+
+
diff --git a/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.scss b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.ts b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.ts new file mode 100644 index 000000000..97ebcd3f4 --- /dev/null +++ b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'redaction-user-profile-screen', + templateUrl: './user-profile.component.html', + styleUrls: ['./user-profile.component.scss'] +}) +export class UserProfileScreenComponent {} diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index c5122764f..2efc511c4 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -1,4 +1,5 @@ { + "account-settings": "Account Settings", "actions": { "all": "All", "none": "None" @@ -228,6 +229,11 @@ "show": "Show", "undo": "Undo" }, + "annotation-engines": { + "dictionary": "Redaction based on dictionary", + "ner": "Redaction based on AI", + "rule": "Redaction based on rule {rule}" + }, "annotation-type": { "add-dictionary": "Pending add to dictionary", "change-legal-basis": "Pending Change of Legal Basis", @@ -1226,10 +1232,7 @@ "user-promoted-to-approver": "{user} promoted to approver in dossier: {dossierName}!", "user-removed-as-dossier-member": "{user} removed as a member of: {dossierName} !" }, - "notifications": { - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}", - "no-data": "You have no notifications." - }, + "notifications": "Notifications", "overwrite-files-dialog": { "options": { "cancel": "Cancel all uploads", @@ -1402,6 +1405,7 @@ "dossiers": "Active Dossiers", "my-account": { "children": { + "account": "Account", "admin": "Settings", "downloads": "My Downloads", "language": { @@ -1410,7 +1414,6 @@ "label": "Language" }, "logout": "Logout", - "my-profile": "My Profile", "trash": "Trash" } } @@ -1482,18 +1485,7 @@ } }, "user-management": "User Management", - "user-profile": { - "actions": { - "change-password": "Change Password", - "save": "Save profile" - }, - "form": { - "email": "Email", - "first-name": "First name", - "last-name": "Last name" - }, - "title": "My profile" - }, + "user-profile": "My Profile", "user-stats": { "chart": { "users": "Users in Workspace" @@ -1521,10 +1513,5 @@ }, "title": "Watermark" }, - "yesterday": "Yesterday", - "annotation-engines": { - "dictionary": "Redaction based on dictionary", - "ner": "Redaction based on AI", - "rule": "Redaction based on rule {rule}" - } + "yesterday": "Yesterday" } diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss index 0a485feeb..acf3e9d8e 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -20,6 +20,7 @@ section.settings { width: calc(100vw - 200px); } + redaction-account-side-nav, redaction-admin-side-nav { height: calc(100vh - 61px); }