move search service, update user wrapper and service
This commit is contained in:
parent
2cb86ab702
commit
9d7c343d5f
@ -78,7 +78,7 @@ export class BaseScreenComponent {
|
||||
}
|
||||
|
||||
get user() {
|
||||
return this._userService.user;
|
||||
return this._userService.currentUser;
|
||||
}
|
||||
|
||||
get showPendingDownloadsDot() {
|
||||
|
||||
@ -2,10 +2,8 @@ import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { FileDownloadService } from '@upload-download/services/file-download.service';
|
||||
import { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper';
|
||||
import { DownloadControllerService } from '@redaction/red-ui-http';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, FilterService, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TableColConfig } from '@shared/components/table-col-name/table-col-name.component';
|
||||
|
||||
@ -13,7 +11,7 @@ import { TableColConfig } from '@shared/components/table-col-name/table-col-name
|
||||
selector: 'redaction-downloads-list-screen',
|
||||
templateUrl: './downloads-list-screen.component.html',
|
||||
styleUrls: ['./downloads-list-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DownloadsListScreenComponent extends BaseListingComponent<DownloadStatusWrapper> implements OnInit {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -98,12 +98,12 @@ export class UserProfileScreenComponent implements OnInit {
|
||||
private _initializeForm(): void {
|
||||
try {
|
||||
this._profileModel = {
|
||||
email: this._userService.user.email,
|
||||
firstName: this._userService.user.firstName,
|
||||
lastName: this._userService.user.lastName,
|
||||
email: this._userService.currentUser.email,
|
||||
firstName: this._userService.currentUser.firstName,
|
||||
lastName: this._userService.currentUser.lastName,
|
||||
language: this._languageService.currentLanguage
|
||||
};
|
||||
if (this._userService.user.email) {
|
||||
if (this._userService.currentUser.email) {
|
||||
// disable email if it's already set
|
||||
this.formGroup.get('email').disable();
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { UserWrapper } from '@services/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-add-edit-user-dialog',
|
||||
@ -10,7 +10,7 @@ import { User } from '@redaction/red-ui-http';
|
||||
export class AddEditUserDialogComponent {
|
||||
resettingPassword = false;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<AddEditUserDialogComponent>, @Inject(MAT_DIALOG_DATA) public user: User) {}
|
||||
constructor(readonly dialogRef: MatDialogRef<AddEditUserDialogComponent>, @Inject(MAT_DIALOG_DATA) readonly user: UserWrapper) {}
|
||||
|
||||
toggleResetPassword() {
|
||||
this.resettingPassword = !this.resettingPassword;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { FormBuilder, Validators } from '@angular/forms';
|
||||
import { UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@Component({
|
||||
@ -10,8 +10,10 @@ import { LoadingService } from '@services/loading.service';
|
||||
styleUrls: ['./reset-password.component.scss']
|
||||
})
|
||||
export class ResetPasswordComponent {
|
||||
passwordForm: FormGroup;
|
||||
@Input() user: User;
|
||||
readonly passwordForm = this._formBuilder.group({
|
||||
temporaryPassword: [null, Validators.required]
|
||||
});
|
||||
@Input() user: UserWrapper;
|
||||
@Output() toggleResetPassword = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
@ -19,14 +21,10 @@ export class ResetPasswordComponent {
|
||||
private readonly _userControllerService: UserControllerService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _loadingService: LoadingService
|
||||
) {
|
||||
this.passwordForm = this._formBuilder.group({
|
||||
temporaryPassword: [null, Validators.required]
|
||||
});
|
||||
}
|
||||
) {}
|
||||
|
||||
get userName() {
|
||||
return this._userService.getNameForId(this.user.userId);
|
||||
return this._userService.getNameForId(this.user.id);
|
||||
}
|
||||
|
||||
async save() {
|
||||
@ -37,7 +35,7 @@ export class ResetPasswordComponent {
|
||||
password: this.passwordForm.get('temporaryPassword').value,
|
||||
temporary: true
|
||||
},
|
||||
this.user.userId
|
||||
this.user.id
|
||||
)
|
||||
.toPromise();
|
||||
this._loadingService.stop();
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserControllerService } from '@redaction/red-ui-http';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { rolesTranslations } from '../../../../../translations/roles-translations';
|
||||
import { IconButtonTypes } from '@iqser/common-ui';
|
||||
import { UserWrapper } from '@services/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-user-details',
|
||||
@ -14,7 +15,7 @@ import { IconButtonTypes } from '@iqser/common-ui';
|
||||
export class UserDetailsComponent implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@Input() user: User;
|
||||
@Input() user: UserWrapper;
|
||||
@Output() toggleResetPassword = new EventEmitter();
|
||||
@Output() closeDialog = new EventEmitter<any>();
|
||||
userForm: FormGroup;
|
||||
@ -99,7 +100,7 @@ export class UserDetailsComponent implements OnInit {
|
||||
if (!this.user) {
|
||||
await this._userControllerService.createUser(userData).toPromise();
|
||||
} else {
|
||||
await this._userControllerService.updateProfile(userData, this.user.userId).toPromise();
|
||||
await this._userControllerService.updateProfile(userData, this.user.id).toPromise();
|
||||
}
|
||||
|
||||
this.closeDialog.emit(true);
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserWrapper } from '@services/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-confirm-delete-users-dialog',
|
||||
@ -11,7 +12,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
styleUrls: ['./confirm-delete-users-dialog.component.scss']
|
||||
})
|
||||
export class ConfirmDeleteUsersDialogComponent {
|
||||
checkboxes = [
|
||||
readonly checkboxes = [
|
||||
{ value: false, label: _('confirm-delete-users.impacted-dossiers') },
|
||||
{ value: false, label: _('confirm-delete-users.impacted-documents') }
|
||||
];
|
||||
@ -22,12 +23,12 @@ export class ConfirmDeleteUsersDialogComponent {
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _userControllerService: UserControllerService,
|
||||
public dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public users: User[]
|
||||
readonly dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly users: UserWrapper[]
|
||||
) {
|
||||
this.dossiersCount = this._appStateService.allDossiers.filter(dw => {
|
||||
for (const user of this.users) {
|
||||
if (dw.memberIds.indexOf(user.userId) !== -1) {
|
||||
if (dw.memberIds.indexOf(user.id) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -42,7 +43,7 @@ export class ConfirmDeleteUsersDialogComponent {
|
||||
async deleteUser() {
|
||||
if (this.valid) {
|
||||
this._loadingService.start();
|
||||
await this._userControllerService.deleteUsers(this.users.map(u => u.userId)).toPromise();
|
||||
await this._userControllerService.deleteUsers(this.users.map(u => u.id)).toPromise();
|
||||
this.dialogRef.close(true);
|
||||
} else {
|
||||
this.showToast = true;
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Field } from '../file-attributes-csv-import-dialog.component';
|
||||
import { FileAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { CircleButtonTypes, FilterService, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { fileAttributeTypesTranslations } from '../../../translations/file-attribute-types-translations';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-active-fields-listing',
|
||||
templateUrl: './active-fields-listing.component.html',
|
||||
styleUrls: ['./active-fields-listing.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class ActiveFieldsListingComponent extends BaseListingComponent<Field> implements OnChanges {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -8,10 +8,7 @@ import { Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { FilterService, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
export interface Field {
|
||||
@ -28,7 +25,7 @@ export interface Field {
|
||||
@Component({
|
||||
templateUrl: './file-attributes-csv-import-dialog.component.html',
|
||||
styleUrls: ['./file-attributes-csv-import-dialog.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class FileAttributesCsvImportDialogComponent extends BaseListingComponent<Field> {
|
||||
protected readonly _primaryKey = 'csvColumn';
|
||||
|
||||
@ -19,7 +19,7 @@ export class SmtpAuthDialogComponent {
|
||||
@Inject(MAT_DIALOG_DATA) public data: SMTPConfigurationModel
|
||||
) {
|
||||
this.authForm = this._formBuilder.group({
|
||||
user: [data?.user || this._userService.user.email, [Validators.required]],
|
||||
user: [data?.user || this._userService.currentUser.email, [Validators.required]],
|
||||
password: [data?.password, Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
@ -5,10 +5,8 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, FilterService, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DefaultColorType } from '@models/default-color-key.model';
|
||||
import { defaultColorsTranslations } from '../../translations/default-colors-translations';
|
||||
|
||||
@ -16,7 +14,7 @@ import { defaultColorsTranslations } from '../../translations/default-colors-tra
|
||||
templateUrl: './default-colors-screen.component.html',
|
||||
styleUrls: ['./default-colors-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DefaultColorsScreenComponent
|
||||
extends BaseListingComponent<{
|
||||
|
||||
@ -9,10 +9,8 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, FilterService, IconButtonTypes, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
@ -25,7 +23,7 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
@Component({
|
||||
templateUrl: './dictionary-listing-screen.component.html',
|
||||
styleUrls: ['./dictionary-listing-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DictionaryListingScreenComponent extends BaseListingComponent<TypeValueWrapper> implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DossierAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, FilterService, IconButtonTypes, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
||||
import { dossierAttributeTypesTranslations } from '../../translations/dossier-attribute-types-translations';
|
||||
@ -15,7 +13,7 @@ import { dossierAttributeTypesTranslations } from '../../translations/dossier-at
|
||||
@Component({
|
||||
templateUrl: './dossier-attributes-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-attributes-listing-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierAttributesListingScreenComponent extends BaseListingComponent<DossierAttributeConfig> implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@ -6,16 +6,14 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
|
||||
import { CircleButtonTypes, FilterService, IconButtonTypes, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-templates-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-templates-listing-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierTemplatesListingScreenComponent extends BaseListingComponent<DossierTemplateModelWrapper> implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@ -5,17 +5,15 @@ import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, FilterService, IconButtonTypes, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { fileAttributeTypesTranslations } from '../../translations/file-attribute-types-translations';
|
||||
|
||||
@Component({
|
||||
templateUrl: './file-attributes-listing-screen.component.html',
|
||||
styleUrls: ['./file-attributes-listing-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class FileAttributesListingScreenComponent extends BaseListingComponent<FileAttributeConfig> implements OnInit, OnDestroy {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@ -4,10 +4,8 @@ import { Dossier } from '@redaction/red-ui-http';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
||||
import * as moment from 'moment';
|
||||
import { CircleButtonTypes, FilterService, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { ConfirmationDialogInput, TitleColors } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
@ -20,7 +18,7 @@ const MINUTES_IN_AN_HOUR = 60;
|
||||
templateUrl: './trash-screen.component.html',
|
||||
styleUrls: ['./trash-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService, DossiersService]
|
||||
providers: [...DefaultListingServices, DossiersService]
|
||||
})
|
||||
export class TrashScreenComponent extends BaseListingComponent<Dossier> implements OnInit {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -87,11 +87,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<redaction-initials-avatar
|
||||
[showYou]="true"
|
||||
[userId]="user.userId"
|
||||
[withName]="true"
|
||||
></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [showYou]="true" [userId]="user.id" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
<div class="small-label">{{ user.email || '-' }}</div>
|
||||
<div class="center">
|
||||
@ -112,7 +108,7 @@
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="openDeleteUsersDialog([user], $event)"
|
||||
[disabled]="user.userId === userService.userId"
|
||||
[disabled]="user.id === userService.currentUser.id"
|
||||
[tooltip]="'user-listing.action.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
import { Component, Injector, OnInit, QueryList, ViewChildren } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import { UserControllerService } from '@redaction/red-ui-http';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
|
||||
import { CircleButtonTypes, FilterService, IconButtonTypes, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { rolesTranslations } from '../../../../translations/roles-translations';
|
||||
@ -19,16 +17,16 @@ import { rolesTranslations } from '../../../../translations/roles-translations';
|
||||
@Component({
|
||||
templateUrl: './user-listing-screen.component.html',
|
||||
styleUrls: ['./user-listing-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class UserListingScreenComponent extends BaseListingComponent<User> implements OnInit {
|
||||
export class UserListingScreenComponent extends BaseListingComponent<UserWrapper> implements OnInit {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly canDeleteSelected$ = this._canDeleteSelected$;
|
||||
collapsedDetails = false;
|
||||
chartData: DoughnutChartConfig[] = [];
|
||||
readonly translations = rolesTranslations;
|
||||
protected readonly _primaryKey = 'userId';
|
||||
protected readonly _primaryKey = 'id';
|
||||
@ViewChildren(InitialsAvatarComponent)
|
||||
private readonly _avatars: QueryList<InitialsAvatarComponent>;
|
||||
|
||||
@ -47,7 +45,7 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
|
||||
get _canDeleteSelected$(): Observable<boolean> {
|
||||
const entities$ = this.screenStateService.selectedEntities$;
|
||||
return entities$.pipe(map(all => all.indexOf(this.userService.user) === -1));
|
||||
return entities$.pipe(map(all => all.indexOf(this.userService.currentUser) === -1));
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@ -55,19 +53,19 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
this.searchService.setSearchKey('searchKey');
|
||||
}
|
||||
|
||||
openAddEditUserDialog($event: MouseEvent, user?: User) {
|
||||
openAddEditUserDialog($event: MouseEvent, user?: UserWrapper) {
|
||||
this._dialogService.openDialog('addEditUser', $event, user, async () => {
|
||||
await this._loadData();
|
||||
});
|
||||
}
|
||||
|
||||
openDeleteUsersDialog(users: User[], $event?: MouseEvent) {
|
||||
openDeleteUsersDialog(users: UserWrapper[], $event?: MouseEvent) {
|
||||
this._dialogService.openDialog('deleteUsers', $event, users, async () => {
|
||||
await this._loadData();
|
||||
});
|
||||
}
|
||||
|
||||
getDisplayRoles(user: User) {
|
||||
getDisplayRoles(user: UserWrapper) {
|
||||
const separator = ', ';
|
||||
return (
|
||||
user.roles.map(role => this._translateService.instant(this.translations[role])).join(separator) ||
|
||||
@ -75,12 +73,12 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
);
|
||||
}
|
||||
|
||||
async toggleActive(user: User) {
|
||||
async toggleActive(user: UserWrapper) {
|
||||
this._loadingService.start();
|
||||
user.roles = this.userService.isActive(user) ? [] : ['RED_USER'];
|
||||
await this._userControllerService.updateProfile(user, user.userId).toPromise();
|
||||
await this._userControllerService.updateProfile(user, user.id).toPromise();
|
||||
await this._loadData();
|
||||
this._avatars.find(item => item.userId === user.userId).detectChanges();
|
||||
this._avatars.find(item => item.userId === user.id).detectChanges();
|
||||
}
|
||||
|
||||
bulkDelete() {
|
||||
@ -108,22 +106,22 @@ export class UserListingScreenComponent extends BaseListingComponent<User> imple
|
||||
label: 'REGULAR'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => this.userService.isManager(user) && !this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter(user => user.isManager && !user.isAdmin).length,
|
||||
color: 'MANAGER',
|
||||
label: 'RED_MANAGER'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => this.userService.isManager(user) && this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter(user => user.isManager && user.isAdmin).length,
|
||||
color: 'MANAGER_ADMIN',
|
||||
label: 'MANAGER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => this.userService.isUserAdmin(user) && !this.userService.isAdmin(user)).length,
|
||||
value: this.allEntities.filter(user => user.isUserAdmin && !user.isAdmin).length,
|
||||
color: 'USER_ADMIN',
|
||||
label: 'RED_USER_ADMIN'
|
||||
},
|
||||
{
|
||||
value: this.allEntities.filter(user => this.userService.isAdmin(user) && !this.userService.isManager(user)).length,
|
||||
value: this.allEntities.filter(user => user.isAdmin && !user.isManager).length,
|
||||
color: 'ADMIN',
|
||||
label: 'RED_ADMIN'
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ export class RedRoleGuard implements CanActivate {
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
return new Observable(obs => {
|
||||
if (!this._userService.user.hasAnyREDRoles) {
|
||||
if (!this._userService.currentUser.hasAnyREDRoles) {
|
||||
this._router.navigate(['/auth-error']);
|
||||
this._loadingService.stop();
|
||||
obs.next(false);
|
||||
@ -26,8 +26,8 @@ export class RedRoleGuard implements CanActivate {
|
||||
// we have at least 1 RED Role -> if it's not user he must be admin
|
||||
|
||||
if (
|
||||
this._userService.user.isUserAdmin &&
|
||||
!this._userService.user.isAdmin &&
|
||||
this._userService.currentUser.isUserAdmin &&
|
||||
!this._userService.currentUser.isAdmin &&
|
||||
!(state.url.startsWith('/main/admin/users') || state.url.startsWith('/main/my-profile'))
|
||||
) {
|
||||
this._router.navigate(['/main/admin/users']);
|
||||
|
||||
@ -5,6 +5,7 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationActionsService } from '../../services/annotation-actions.service';
|
||||
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
export const AnnotationButtonTypes = {
|
||||
dark: 'dark',
|
||||
@ -28,9 +29,10 @@ export class AnnotationActionsComponent implements OnInit {
|
||||
annotationPermissions: AnnotationPermissions;
|
||||
|
||||
constructor(
|
||||
public appStateService: AppStateService,
|
||||
public annotationActionsService: AnnotationActionsService,
|
||||
private _permissionsService: PermissionsService
|
||||
readonly appStateService: AppStateService,
|
||||
readonly annotationActionsService: AnnotationActionsService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _userService: UserService
|
||||
) {}
|
||||
|
||||
private _annotations: AnnotationWrapper[];
|
||||
@ -89,7 +91,7 @@ export class AnnotationActionsComponent implements OnInit {
|
||||
private _setPermissions() {
|
||||
this.annotationPermissions = AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(),
|
||||
this._permissionsService.currentUser,
|
||||
this._userService.currentUser,
|
||||
this.annotations
|
||||
);
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ export class CommentsComponent {
|
||||
this.annotation.comments.push({
|
||||
text: value,
|
||||
id: commentResponse.commentId,
|
||||
user: this._userService.userId
|
||||
user: this._userService.currentUser.id
|
||||
});
|
||||
});
|
||||
this.commentForm.reset();
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<div class="all-caps-label" translate="dossier-details.owner"></div>
|
||||
<div class="mt-12 d-flex">
|
||||
<ng-container *ngIf="!editingOwner; else editOwner">
|
||||
<redaction-initials-avatar [userId]="owner?.userId" [withName]="true" color="gray" size="large"></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="owner?.id" [withName]="true" color="gray" size="large"></redaction-initials-avatar>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="editingOwner = true"
|
||||
|
||||
@ -5,8 +5,7 @@ import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/si
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { FilterService } from '@iqser/common-ui';
|
||||
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
|
||||
@ -20,7 +19,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
})
|
||||
export class DossierDetailsComponent implements OnInit {
|
||||
documentsChartData: DoughnutChartConfig[] = [];
|
||||
owner: User;
|
||||
owner: UserWrapper;
|
||||
editingOwner = false;
|
||||
@Input() dossierAttributes: DossierAttributeWithValue[];
|
||||
@Output() openAssignDossierMembersDialog = new EventEmitter();
|
||||
@ -81,13 +80,13 @@ export class DossierDetailsComponent implements OnInit {
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
async assignOwner(user: User | string) {
|
||||
async assignOwner(user: UserWrapper | string) {
|
||||
this.owner = typeof user === 'string' ? this._userService.getRedUserById(user) : user;
|
||||
const dw = Object.assign({}, this.appStateService.activeDossier);
|
||||
dw.dossier.ownerId = this.owner.userId;
|
||||
dw.dossier.ownerId = this.owner.id;
|
||||
await this.appStateService.createOrUpdateDossier(dw.dossier);
|
||||
|
||||
const ownerName = this._userService.getNameForId(this.owner.userId);
|
||||
const ownerName = this._userService.getNameForId(this.owner.id);
|
||||
const dossierName = this.appStateService.activeDossier.name;
|
||||
const msg = 'Successfully assigned ' + ownerName + ' to dossier: ' + dossierName;
|
||||
this._toaster.info(msg);
|
||||
|
||||
@ -43,15 +43,15 @@ export class TeamMembersManagerComponent implements OnInit {
|
||||
}
|
||||
|
||||
get ownersSelectOptions() {
|
||||
return this.userService.managerUsers.map(m => m.userId);
|
||||
return this.userService.managerUsers.map(m => m.id);
|
||||
}
|
||||
|
||||
get membersSelectOptions() {
|
||||
const searchQuery = this.searchForm.get('query').value;
|
||||
return this.userService.eligibleUsers
|
||||
.filter(user => this.userService.getNameForId(user.userId).toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
.filter(user => this.selectedOwnerId !== user.userId)
|
||||
.map(user => user.userId);
|
||||
.filter(user => this.userService.getNameForId(user.id).toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
.filter(user => this.selectedOwnerId !== user.id)
|
||||
.map(user => user.id);
|
||||
}
|
||||
|
||||
get valid(): boolean {
|
||||
|
||||
@ -103,7 +103,7 @@ export class AssignReviewerApproverDialogComponent {
|
||||
uniqueReviewers.add(file.currentReviewer);
|
||||
}
|
||||
}
|
||||
let singleUser = uniqueReviewers.size === 1 ? uniqueReviewers.values().next().value : this.userService.userId;
|
||||
let singleUser = uniqueReviewers.size === 1 ? uniqueReviewers.values().next().value : this.userService.currentUser.id;
|
||||
|
||||
singleUser = this.singleUsersSelectOptions.indexOf(singleUser) >= 0 ? singleUser : this.singleUsersSelectOptions[0];
|
||||
|
||||
|
||||
@ -16,10 +16,8 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
|
||||
import { FilterService, NestedFilter, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { NestedFilter } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { TableColConfig } from '@shared/components/table-col-name/table-col-name.component';
|
||||
import { workloadTranslations } from '../../translations/workload-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -36,14 +34,14 @@ const isLeavingScreen = event => event instanceof NavigationStart && event.url !
|
||||
@Component({
|
||||
templateUrl: './dossier-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-listing-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierListingScreenComponent
|
||||
extends BaseListingComponent<DossierWrapper>
|
||||
implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach
|
||||
{
|
||||
readonly itemSize = 95;
|
||||
buttonConfigs: ButtonConfig[] = [
|
||||
readonly buttonConfigs: ButtonConfig[] = [
|
||||
{
|
||||
label: _('dossier-listing.add-new'),
|
||||
action: () => this.openAddDossierDialog(),
|
||||
@ -52,7 +50,7 @@ export class DossierListingScreenComponent
|
||||
type: 'primary'
|
||||
}
|
||||
];
|
||||
tableColConfigs: TableColConfig[] = [
|
||||
readonly tableColConfigs: TableColConfig[] = [
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.name'),
|
||||
withSort: true,
|
||||
@ -72,7 +70,7 @@ export class DossierListingScreenComponent
|
||||
];
|
||||
dossiersChartData: DoughnutChartConfig[] = [];
|
||||
documentsChartData: DoughnutChartConfig[] = [];
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
protected readonly _primaryKey = 'numberOfMembers';
|
||||
protected _tableHeaderLabel = _('dossier-listing.table-header.title');
|
||||
private _lastScrollPosition: number;
|
||||
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||
@ -95,7 +93,7 @@ export class DossierListingScreenComponent
|
||||
}
|
||||
|
||||
private get _userId() {
|
||||
return this._userService.userId;
|
||||
return this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
private get _activeDossiersCount(): number {
|
||||
|
||||
@ -21,10 +21,8 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
||||
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
||||
import { CircleButtonTypes, FilterService, keyChecker, NestedFilter, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, keyChecker, NestedFilter } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
||||
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
|
||||
@ -38,7 +36,7 @@ import { annotationFilterChecker } from '@shared/components/filters/popup-filter
|
||||
@Component({
|
||||
templateUrl: './dossier-overview-screen.component.html',
|
||||
styleUrls: ['./dossier-overview-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierOverviewScreenComponent
|
||||
extends BaseListingComponent<FileStatusWrapper>
|
||||
@ -60,7 +58,7 @@ export class DossierOverviewScreenComponent
|
||||
}
|
||||
];
|
||||
dossierAttributes: DossierAttributeWithValue[] = [];
|
||||
tableColConfigs: TableColConfig[] = [
|
||||
readonly tableColConfigs: TableColConfig[] = [
|
||||
{
|
||||
label: _('dossier-overview.table-col-names.name'),
|
||||
withSort: true,
|
||||
@ -125,7 +123,7 @@ export class DossierOverviewScreenComponent
|
||||
}
|
||||
|
||||
get userId() {
|
||||
return this._userService.userId;
|
||||
return this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
get checkedRequiredFilters() {
|
||||
|
||||
@ -17,12 +17,11 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { timer } from 'rxjs';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import {
|
||||
FileManagementControllerService,
|
||||
FileStatus,
|
||||
StatusControllerService,
|
||||
User,
|
||||
UserPreferenceControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
|
||||
@ -34,10 +33,8 @@ import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { stampPDFPage } from '@utils/page-stamper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AutoUnsubscribeComponent, CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribeComponent, CircleButtonTypes, NestedFilter, processFilters } from '@iqser/common-ui';
|
||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||
import { NestedFilter } from '@iqser/common-ui';
|
||||
import { processFilters } from '@iqser/common-ui';
|
||||
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
|
||||
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
||||
@ -276,7 +273,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme
|
||||
const processStartTime = new Date().getTime();
|
||||
this.annotationData = this.fileData.getAnnotations(
|
||||
this.appStateService.dictionaryData[this.appStateService.activeDossier.dossierTemplateId],
|
||||
this.permissionsService.currentUser,
|
||||
this.userService.currentUser,
|
||||
this.viewMode,
|
||||
this.userPreferenceService.areDevFeaturesEnabled
|
||||
);
|
||||
@ -467,8 +464,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme
|
||||
});
|
||||
}
|
||||
|
||||
async assignReviewer(user: User | string) {
|
||||
const reviewerId = typeof user === 'string' ? user : user.userId;
|
||||
async assignReviewer(user: UserWrapper | string) {
|
||||
const reviewerId = typeof user === 'string' ? user : user.id;
|
||||
const reviewerName = this.userService.getNameForId(reviewerId);
|
||||
|
||||
const { dossierId, fileId, filename } = this.fileData.fileStatus;
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { Component, Injector, OnDestroy } from '@angular/core';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { MatchedDocument, SearchControllerService, SearchResult } from '@redaction/red-ui-http';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { debounceTime, map, skip, switchMap, tap } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { TableColConfig } from '@shared/components/table-col-name/table-col-name.component';
|
||||
import { FilterService, keyChecker, SortingService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
import { keyChecker } from '@iqser/common-ui';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
@ -36,7 +34,7 @@ interface SearchInput {
|
||||
@Component({
|
||||
templateUrl: './search-screen.component.html',
|
||||
styleUrls: ['./search-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class SearchScreenComponent extends BaseListingComponent<ListItem> implements OnDestroy {
|
||||
readonly fileStatusTranslations = fileStatusTranslations;
|
||||
@ -65,7 +63,7 @@ export class SearchScreenComponent extends BaseListingComponent<ListItem> implem
|
||||
label: _('search-screen.cols.pages')
|
||||
}
|
||||
];
|
||||
protected readonly _primaryKey = 'fileName';
|
||||
protected readonly _primaryKey = 'filename';
|
||||
protected readonly _tableHeaderLabel = _('search-screen.table-header');
|
||||
|
||||
constructor(
|
||||
|
||||
@ -9,13 +9,15 @@ import { getFirstRelevantTextPart } from '@utils/functions';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { DossiersDialogService } from './dossiers-dialog.service';
|
||||
import { BASE_HREF } from '../../../tokens';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationActionsService {
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _ngZone: NgZone,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _manualAnnotationService: ManualAnnotationService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _dialogService: DossiersDialogService
|
||||
@ -89,7 +91,7 @@ export class AnnotationActionsService {
|
||||
annotations.forEach(annotation => {
|
||||
const permissions = AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(),
|
||||
this._permissionsService.currentUser,
|
||||
this._userService.currentUser,
|
||||
annotation
|
||||
);
|
||||
const value = permissions.canMarkTextOnlyAsFalsePositive ? annotation.value : this._getFalsePositiveText(annotation);
|
||||
@ -132,9 +134,9 @@ export class AnnotationActionsService {
|
||||
): Record<string, unknown>[] {
|
||||
const availableActions = [];
|
||||
|
||||
const annotationPermissions = annotations.map(a => ({
|
||||
annotation: a,
|
||||
permissions: AnnotationPermissions.forUser(this._permissionsService.isApprover(), this._permissionsService.currentUser, a)
|
||||
const annotationPermissions = annotations.map(annotation => ({
|
||||
annotation,
|
||||
permissions: AnnotationPermissions.forUser(this._permissionsService.isApprover(), this._userService.currentUser, annotation)
|
||||
}));
|
||||
|
||||
const canRecategorizeImage = annotations.length === 1 && annotationPermissions[0].permissions.canRecategorizeImage;
|
||||
|
||||
@ -154,7 +154,7 @@ export class FileActionService {
|
||||
.setFileReviewerForList(
|
||||
fileStatus.map(f => f.fileId),
|
||||
this._appStateService.activeDossierId,
|
||||
this._userService.userId
|
||||
this._userService.currentUser.id
|
||||
)
|
||||
.toPromise();
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
import { Component, Injector, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { AutoUnsubscribeComponent, FilterService, SortingOrders, SortingService } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribeComponent, FilterService, KeysOf, SearchService, SortingOrders, SortingService } from '@iqser/common-ui';
|
||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
import { SearchService } from '../services/search.service';
|
||||
import { ScreenStateService } from '../services/screen-state.service';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
export const DefaultListingServices = [FilterService, SearchService, ScreenStateService, SortingService] as const;
|
||||
|
||||
@Component({ template: '' })
|
||||
export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
export abstract class BaseListingComponent<T extends object> extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
@ViewChild(CdkVirtualScrollViewport)
|
||||
readonly scrollViewport: CdkVirtualScrollViewport;
|
||||
|
||||
readonly permissionsService = this._injector.get(PermissionsService);
|
||||
readonly filterService = this._injector.get(FilterService);
|
||||
readonly sortingService = this._injector.get(SortingService);
|
||||
readonly searchService = this._injector.get(SearchService);
|
||||
readonly sortingService = this._injector.get<SortingService<T>>(SortingService);
|
||||
readonly searchService = this._injector.get<SearchService<T>>(SearchService);
|
||||
readonly screenStateService = this._injector.get<ScreenStateService<T>>(ScreenStateService);
|
||||
|
||||
readonly sortedDisplayedEntities$ = this._sortedDisplayedEntities$;
|
||||
@ -27,7 +28,7 @@ export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent i
|
||||
* and in the default sorting and as the search field
|
||||
* @protected
|
||||
*/
|
||||
protected abstract _primaryKey: string;
|
||||
protected readonly _primaryKey: KeysOf<T>;
|
||||
|
||||
protected constructor(protected readonly _injector: Injector) {
|
||||
super();
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-assign-user-dropdown',
|
||||
@ -9,25 +8,25 @@ import { UserService } from '@services/user.service';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class AssignUserDropdownComponent {
|
||||
oldUser: User | string;
|
||||
@Input() options: (User | string)[];
|
||||
@Output() save = new EventEmitter<User | string>();
|
||||
oldUser: UserWrapper | string;
|
||||
@Input() options: (UserWrapper | string)[];
|
||||
@Output() save = new EventEmitter<UserWrapper | string>();
|
||||
@Output() cancel = new EventEmitter<never>();
|
||||
private _currentUser: User | string;
|
||||
private _currentUser: UserWrapper | string;
|
||||
|
||||
constructor(private readonly _userService: UserService) {}
|
||||
|
||||
get value(): User | string {
|
||||
get value(): UserWrapper | string {
|
||||
return this._currentUser;
|
||||
}
|
||||
|
||||
@Input()
|
||||
set value(value: User | string) {
|
||||
set value(value: UserWrapper | string) {
|
||||
if (this.oldUser === undefined) this.oldUser = value;
|
||||
this._currentUser = value;
|
||||
}
|
||||
|
||||
getContext(user: User | string) {
|
||||
return { userId: typeof user === 'string' ? user : user?.userId };
|
||||
getContext(user: UserWrapper | string) {
|
||||
return { userId: typeof user === 'string' ? user : user?.id };
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<button [class.overlay]="showDot" mat-button>
|
||||
<redaction-initials-avatar [userId]="user.userId" [withName]="true" size="small"></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="user.id" [withName]="true" size="small"></redaction-initials-avatar>
|
||||
<mat-icon svgIcon="iqser:arrow-down"></mat-icon>
|
||||
</button>
|
||||
<div *ngIf="showDot" class="dot"></div>
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { AutoUnsubscribeComponent } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-initials-avatar',
|
||||
@ -10,7 +9,7 @@ import { Subscription } from 'rxjs';
|
||||
styleUrls: ['./initials-avatar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class InitialsAvatarComponent implements OnChanges, OnDestroy {
|
||||
export class InitialsAvatarComponent extends AutoUnsubscribeComponent implements OnChanges, OnDestroy {
|
||||
@Input() userId: string;
|
||||
@Input() color = 'lightgray';
|
||||
@Input() size: 'small' | 'large' = 'small';
|
||||
@ -21,22 +20,21 @@ export class InitialsAvatarComponent implements OnChanges, OnDestroy {
|
||||
displayName: string;
|
||||
initials: string;
|
||||
colorClass: string;
|
||||
user: User;
|
||||
|
||||
private _subscription: Subscription;
|
||||
user: UserWrapper;
|
||||
|
||||
constructor(
|
||||
private readonly _userService: UserService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef
|
||||
) {
|
||||
this._subscription = _userService.usersReloaded$.subscribe(() => {
|
||||
super();
|
||||
this.addSubscription = _userService.usersReloaded$.subscribe(() => {
|
||||
this.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
get hasBorder(): boolean {
|
||||
return !!this.user && !this._isCurrentUser && this._userService.isManager(this.user);
|
||||
return !!this.user && !this._isCurrentUser && this.user.isManager;
|
||||
}
|
||||
|
||||
get disabled(): boolean {
|
||||
@ -52,11 +50,7 @@ export class InitialsAvatarComponent implements OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
private get _isCurrentUser(): boolean {
|
||||
return this._userService.userId === this.user?.userId;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._subscription?.unsubscribe();
|
||||
return this._userService.currentUser.id === this.user?.id;
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { Component, Input, Optional } from '@angular/core';
|
||||
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
||||
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
|
||||
import { FilterService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { FilterService, SearchService } from '@iqser/common-ui';
|
||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import { combineLatest, Observable, of } from 'rxjs';
|
||||
import { SearchPosition, SearchPositions } from '@shared/components/page-header/models/search-positions.type';
|
||||
@ -12,7 +11,7 @@ import { SearchPosition, SearchPositions } from '@shared/components/page-header/
|
||||
templateUrl: './page-header.component.html',
|
||||
styleUrls: ['./page-header.component.scss']
|
||||
})
|
||||
export class PageHeaderComponent {
|
||||
export class PageHeaderComponent<T extends object> {
|
||||
readonly searchPositions = SearchPositions;
|
||||
|
||||
@Input() pageLabel: string;
|
||||
@ -26,7 +25,7 @@ export class PageHeaderComponent {
|
||||
readonly filters$ = this.filterService?.filterGroups$.pipe(map(all => all.filter(f => f.icon)));
|
||||
readonly showResetFilters$ = this._showResetFilters$;
|
||||
|
||||
constructor(@Optional() readonly filterService: FilterService, @Optional() readonly searchService: SearchService) {}
|
||||
constructor(@Optional() readonly filterService: FilterService, @Optional() readonly searchService: SearchService<T>) {}
|
||||
|
||||
get _showResetFilters$(): Observable<boolean> {
|
||||
if (!this.filterService) return of(false);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component, Input, Optional } from '@angular/core';
|
||||
import { SortingService } from '@iqser/common-ui';
|
||||
import { KeysOf, SortingService } from '@iqser/common-ui';
|
||||
|
||||
export interface TableColConfig {
|
||||
readonly column?: string;
|
||||
@ -16,8 +16,8 @@ export interface TableColConfig {
|
||||
templateUrl: './table-col-name.component.html',
|
||||
styleUrls: ['./table-col-name.component.scss']
|
||||
})
|
||||
export class TableColNameComponent {
|
||||
@Input() column: string;
|
||||
export class TableColNameComponent<T extends object> {
|
||||
@Input() column: KeysOf<T>;
|
||||
@Input() label: string;
|
||||
@Input() withSort = false;
|
||||
@Input() class: string;
|
||||
@ -25,5 +25,5 @@ export class TableColNameComponent {
|
||||
@Input() rightIcon: string;
|
||||
@Input() rightIconTooltip: string;
|
||||
|
||||
constructor(@Optional() readonly sortingService: SortingService) {}
|
||||
constructor(@Optional() readonly sortingService: SortingService<T>) {}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import { ScreenStateService } from '@shared/services/screen-state.service';
|
||||
styleUrls: ['./table-header.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class TableHeaderComponent<T> {
|
||||
export class TableHeaderComponent<T extends object> {
|
||||
@Input() tableHeaderLabel: string;
|
||||
@Input() tableColConfigs: TableColConfig[];
|
||||
@Input() hasEmptyColumn = false;
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, combineLatest, Observable, pipe } from 'rxjs';
|
||||
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
|
||||
import { FilterService } from '@iqser/common-ui';
|
||||
import { SearchService } from '@shared/services/search.service';
|
||||
import { getFilteredEntities } from '@iqser/common-ui';
|
||||
import { FilterService, getFilteredEntities, SearchService } from '@iqser/common-ui';
|
||||
|
||||
const toLengthValue = (entities: unknown[]) => entities?.length ?? 0;
|
||||
const getLength = pipe(map(toLengthValue), distinctUntilChanged());
|
||||
|
||||
@Injectable()
|
||||
export class ScreenStateService<T> {
|
||||
export class ScreenStateService<T extends object> {
|
||||
private readonly _allEntities$ = new BehaviorSubject<T[]>([]);
|
||||
readonly allEntities$ = this._allEntities$.asObservable();
|
||||
readonly allEntitiesLength$ = this._allEntities$.pipe(getLength);
|
||||
@ -27,7 +25,7 @@ export class ScreenStateService<T> {
|
||||
readonly areSomeEntitiesSelected$ = this._areSomeEntitiesSelected$;
|
||||
readonly notAllEntitiesSelected$ = this._notAllEntitiesSelected$;
|
||||
|
||||
constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService) {
|
||||
constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService<T>) {
|
||||
// setInterval(() => {
|
||||
// console.log('All entities subs: ', this._allEntities$.observers);
|
||||
// console.log('Displayed entities subs: ', this._displayedEntities$.observers);
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { startWith } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class SearchService {
|
||||
readonly searchForm = this._formBuilder.group({
|
||||
query: ['']
|
||||
});
|
||||
readonly valueChanges$ = this.searchForm.get('query').valueChanges.pipe(startWith(''));
|
||||
private _searchKey: string;
|
||||
|
||||
constructor(private readonly _formBuilder: FormBuilder) {}
|
||||
|
||||
get searchValue(): string {
|
||||
return this.searchForm.get('query').value;
|
||||
}
|
||||
|
||||
set searchValue(value: string) {
|
||||
this.searchForm.patchValue({ query: value });
|
||||
}
|
||||
|
||||
searchIn<T>(entities: T[]) {
|
||||
if (!this._searchKey) return entities;
|
||||
|
||||
const searchValue = this.searchValue.toLowerCase();
|
||||
return entities.filter(entity => this._searchField(entity).includes(searchValue));
|
||||
}
|
||||
|
||||
setSearchKey(value: string): void {
|
||||
this._searchKey = value;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.searchForm.reset({ query: '' }, { emitEvent: true });
|
||||
}
|
||||
|
||||
private _searchField<T>(entity: T): string {
|
||||
return entity[this._searchKey].toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService, UserWrapper } from './user.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { User, Comment } from '@redaction/red-ui-http';
|
||||
import { Comment } from '@redaction/red-ui-http';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
|
||||
@Injectable({
|
||||
@ -11,10 +11,6 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
export class PermissionsService {
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _userService: UserService) {}
|
||||
|
||||
get currentUser(): UserWrapper {
|
||||
return this._userService.user;
|
||||
}
|
||||
|
||||
private get _activeFile(): FileStatusWrapper | undefined {
|
||||
return this._appStateService.activeFile;
|
||||
}
|
||||
@ -23,7 +19,7 @@ export class PermissionsService {
|
||||
return this._appStateService.activeDossier;
|
||||
}
|
||||
|
||||
isManager(user?: User) {
|
||||
isManager(user?: UserWrapper) {
|
||||
return this._userService.isManager(user);
|
||||
}
|
||||
|
||||
@ -55,7 +51,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
isFileReviewer(fileStatus = this._activeFile): boolean {
|
||||
return fileStatus.currentReviewer === this._userService.userId;
|
||||
return fileStatus.currentReviewer === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
canDeleteFile(fileStatus = this._activeFile, dossier?: DossierWrapper): boolean {
|
||||
@ -112,19 +108,19 @@ export class PermissionsService {
|
||||
return fileStatus?.isUnderReview && this.isReviewerOrApprover(fileStatus);
|
||||
}
|
||||
|
||||
isOwner(dossier = this._activeDossier, user = this.currentUser): boolean {
|
||||
isOwner(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
|
||||
return dossier?.ownerId === user.id;
|
||||
}
|
||||
|
||||
isApprover(dossier = this._activeDossier, user = this.currentUser): boolean {
|
||||
isApprover(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
|
||||
return dossier?.approverIds.indexOf(user.id) >= 0;
|
||||
}
|
||||
|
||||
isDossierReviewer(dossier = this._activeDossier, user = this.currentUser): boolean {
|
||||
isDossierReviewer(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
|
||||
return this.isDossierMember(dossier, user) && !this.isApprover(dossier, user);
|
||||
}
|
||||
|
||||
isDossierMember(dossier = this._activeDossier, user = this.currentUser): boolean {
|
||||
isDossierMember(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
|
||||
return dossier?.memberIds.includes(user.id);
|
||||
}
|
||||
|
||||
@ -156,18 +152,18 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canDeleteDossier(dossier = this._activeDossier): boolean {
|
||||
return dossier.ownerId === this.currentUser.userId;
|
||||
return dossier.ownerId === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
isAdmin(user = this.currentUser): boolean {
|
||||
isAdmin(user = this._userService.currentUser): boolean {
|
||||
return user.isAdmin;
|
||||
}
|
||||
|
||||
isUserAdmin(user = this.currentUser): boolean {
|
||||
isUserAdmin(user = this._userService.currentUser): boolean {
|
||||
return user.isUserAdmin;
|
||||
}
|
||||
|
||||
isUser(user = this.currentUser): boolean {
|
||||
isUser(user = this._userService.currentUser): boolean {
|
||||
return user.isUser;
|
||||
}
|
||||
|
||||
@ -190,6 +186,6 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canDeleteComment(comment: Comment, fileStatus = this._activeFile) {
|
||||
return (comment.user === this._userService.userId || this.isApprover()) && !fileStatus.isApproved;
|
||||
return (comment.user === this._userService.currentUser.id || this.isApprover()) && !fileStatus.isApproved;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { EventEmitter, Inject, Injectable } from '@angular/core';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { KeycloakProfile } from 'keycloak-js';
|
||||
import jwt_decode from 'jwt-decode';
|
||||
import { User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { wipeCaches } from '@redaction/red-cache';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
export interface ProfileModel {
|
||||
username?: string;
|
||||
@ -15,62 +16,27 @@ export interface ProfileModel {
|
||||
}
|
||||
|
||||
export class UserWrapper {
|
||||
name: string;
|
||||
constructor(private readonly _user: KeycloakProfile | User, public roles: string[], public id: string) {}
|
||||
|
||||
constructor(private readonly _currentUser: KeycloakProfile | User, public roles: string[], public id: string) {
|
||||
this.name = this.firstName && this.lastName ? `${this.firstName} ${this.lastName}` : this.username;
|
||||
}
|
||||
email = this._user.email;
|
||||
username = this._user.username || this.email;
|
||||
firstName = this._user.firstName;
|
||||
lastName = this._user.lastName;
|
||||
name = this.firstName && this.lastName ? `${this.firstName} ${this.lastName}` : this.username;
|
||||
searchKey = this.name + this.username + this.email;
|
||||
|
||||
get username() {
|
||||
return this._currentUser.username || this.email;
|
||||
}
|
||||
|
||||
get userId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
get email() {
|
||||
return this._currentUser.email;
|
||||
}
|
||||
|
||||
get firstName() {
|
||||
return this._currentUser.firstName;
|
||||
}
|
||||
|
||||
get lastName() {
|
||||
return this._currentUser.lastName;
|
||||
}
|
||||
|
||||
get searchKey() {
|
||||
return this.name + this.username + this.email;
|
||||
}
|
||||
|
||||
get isManager() {
|
||||
return this.roles.indexOf('RED_MANAGER') >= 0;
|
||||
}
|
||||
|
||||
get isUserAdmin() {
|
||||
return this.roles.indexOf('RED_USER_ADMIN') >= 0;
|
||||
}
|
||||
|
||||
get isUser() {
|
||||
return this.roles.indexOf('RED_USER') >= 0;
|
||||
}
|
||||
|
||||
get isAdmin() {
|
||||
return this.roles.indexOf('RED_ADMIN') >= 0;
|
||||
}
|
||||
|
||||
get hasAnyREDRoles() {
|
||||
return this.isUser || this.isManager || this.isAdmin || this.isUserAdmin;
|
||||
}
|
||||
isManager = this.roles.indexOf('RED_MANAGER') >= 0;
|
||||
isUserAdmin = this.roles.indexOf('RED_USER_ADMIN') >= 0;
|
||||
isUser = this.roles.indexOf('RED_USER') >= 0;
|
||||
isAdmin = this.roles.indexOf('RED_ADMIN') >= 0;
|
||||
hasAnyREDRoles = this.isUser || this.isManager || this.isAdmin || this.isUserAdmin;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserService {
|
||||
usersReloaded$: EventEmitter<any> = new EventEmitter<any>();
|
||||
usersReloaded$ = new Subject();
|
||||
private _currentUser: UserWrapper;
|
||||
private _allUsers: UserWrapper[];
|
||||
|
||||
@ -86,31 +52,18 @@ export class UserService {
|
||||
return this._allRedUsers;
|
||||
}
|
||||
|
||||
get userId(): string {
|
||||
return this._currentUser.id;
|
||||
}
|
||||
|
||||
get managerUsers(): UserWrapper[] {
|
||||
return this._allRedUsers.filter(u => u.roles.indexOf('RED_MANAGER') >= 0);
|
||||
return this._allRedUsers.filter(user => user.isManager);
|
||||
}
|
||||
|
||||
get eligibleUsers(): UserWrapper[] {
|
||||
return this._allRedUsers.filter(u => u.roles.indexOf('RED_USER') >= 0 || u.roles.indexOf('RED_MANAGER') >= 0);
|
||||
return this._allRedUsers.filter(user => user.isUser || user.isManager);
|
||||
}
|
||||
|
||||
get user() {
|
||||
get currentUser(): UserWrapper {
|
||||
return this._currentUser;
|
||||
}
|
||||
|
||||
private static _hasAnyRedRole(user: UserWrapper) {
|
||||
return (
|
||||
user.roles.indexOf('RED_USER') >= 0 ||
|
||||
user.roles.indexOf('RED_MANAGER') >= 0 ||
|
||||
user.roles.indexOf('RED_ADMIN') >= 0 ||
|
||||
user.roles.indexOf('RED_USER_ADMIN') >= 0
|
||||
);
|
||||
}
|
||||
|
||||
logout() {
|
||||
wipeCaches().then();
|
||||
this._keycloakService.logout(window.location.origin + this._baseHref).then();
|
||||
@ -123,14 +76,14 @@ export class UserService {
|
||||
}
|
||||
|
||||
async loadAllUsers() {
|
||||
let allUsers = [];
|
||||
let allUsers: User[];
|
||||
if (this._currentUser.isUserAdmin) {
|
||||
allUsers = await this._userControllerService.getAllUsers().toPromise();
|
||||
} else {
|
||||
allUsers = await this._userControllerService.getUsers().toPromise();
|
||||
}
|
||||
this._allUsers = allUsers.map(user => new UserWrapper(user, user.roles, user.userId));
|
||||
this._allRedUsers = this._allUsers.filter(u => UserService._hasAnyRedRole(u));
|
||||
this._allRedUsers = this._allUsers.filter(user => user.hasAnyREDRoles);
|
||||
this.usersReloaded$.next();
|
||||
return this._allUsers;
|
||||
}
|
||||
@ -147,42 +100,43 @@ export class UserService {
|
||||
}
|
||||
|
||||
getRedUserById(id: string) {
|
||||
return this._allRedUsers.find(u => u.userId === id);
|
||||
return this._allRedUsers.find(u => u.id === id);
|
||||
}
|
||||
|
||||
getUserById(id: string) {
|
||||
return this._allUsers ? this._allUsers.find(u => u.userId === id) : this.getRedUserById(id);
|
||||
return this._allUsers ? this._allUsers.find(u => u.id === id) : this.getRedUserById(id);
|
||||
}
|
||||
|
||||
getNameForId(userId: string) {
|
||||
return this.getName(this.getUserById(userId));
|
||||
getNameForId(userId: string): string | undefined {
|
||||
const user = this.getUserById(userId);
|
||||
return user ? this.getName(user) : undefined;
|
||||
}
|
||||
|
||||
getName({ firstName, lastName, username }: User = {}) {
|
||||
getName({ firstName, lastName, username }: UserWrapper) {
|
||||
return firstName && lastName ? `${firstName} ${lastName}` : username;
|
||||
}
|
||||
|
||||
isManager(user: User | UserWrapper = this.user): boolean {
|
||||
isManager(user: UserWrapper = this._currentUser): boolean {
|
||||
return user.roles.indexOf('RED_MANAGER') >= 0;
|
||||
}
|
||||
|
||||
isUser(user: User | UserWrapper = this.user): boolean {
|
||||
isUser(user: UserWrapper = this._currentUser): boolean {
|
||||
return user.roles?.indexOf('RED_USER') >= 0;
|
||||
}
|
||||
|
||||
isUserAdmin(user: User | UserWrapper = this.user): boolean {
|
||||
isUserAdmin(user: UserWrapper = this._currentUser): boolean {
|
||||
return user.roles?.indexOf('RED_USER_ADMIN') >= 0;
|
||||
}
|
||||
|
||||
isAdmin(user: User | UserWrapper = this.user): boolean {
|
||||
isAdmin(user: UserWrapper = this._currentUser): boolean {
|
||||
return user.roles?.indexOf('RED_ADMIN') >= 0;
|
||||
}
|
||||
|
||||
isActive(user: User | UserWrapper = this.user): boolean {
|
||||
isActive(user: UserWrapper = this._currentUser): boolean {
|
||||
return user.roles?.length > 0;
|
||||
}
|
||||
|
||||
hasAnyRole(requiredRoles: string[], user: User | UserWrapper = this.user) {
|
||||
hasAnyRole(requiredRoles: string[], user: UserWrapper = this._currentUser) {
|
||||
if (requiredRoles?.length > 0) {
|
||||
for (const role of requiredRoles) if (user.roles.indexOf(role) >= 0) return true;
|
||||
|
||||
|
||||
@ -14,11 +14,11 @@ export class AppStateGuard implements CanActivate {
|
||||
) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
if (this._userService.user.isUserAdmin) {
|
||||
if (this._userService.currentUser.isUserAdmin) {
|
||||
await this._userService.loadUsersIfNecessary();
|
||||
}
|
||||
|
||||
if (this._userService.user.isUser || this._userService.user.isAdmin) {
|
||||
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
|
||||
await this._userService.loadUsersIfNecessary();
|
||||
await this._appStateService.loadDossierTemplatesIfNecessary();
|
||||
await this._appStateService.loadDictionaryDataIfNecessary();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user