Pull request #297: Red ui http remove

Merge in RED/ui from red-ui-http-remove to master

* commit '49931c13de9dd6414ad579078b5c3da36490661a':
  fix lint
  update file download service
  update dossier attributes service
  create digital signature service
  create service for audit
  update dossier templates service
  update common lib
  cast objects, find bugs
  update user service, name pipe, initials avatars
  update common ui
  update user preference service
This commit is contained in:
Dan Percic 2021-10-07 15:25:59 +02:00
commit d76be025bf
63 changed files with 540 additions and 445 deletions

View File

@ -14,5 +14,9 @@ max_line_length = 140
max_line_length = off max_line_length = off
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.ts]
ij_typescript_use_double_quotes = false
ij_typescript_enforce_trailing_comma = keep
[{*.json, .prettierrc, .eslintrc}] [{*.json, .prettierrc, .eslintrc}]
indent_size = 2 indent_size = 2

View File

@ -184,6 +184,7 @@
"prefer-const": "error", "prefer-const": "error",
"radix": "error", "radix": "error",
"curly": "error", "curly": "error",
"quotes": ["error", "single"],
"comma-dangle": [ "comma-dangle": [
"error", "error",
{ {

View File

@ -24,8 +24,8 @@
></iqser-circle-button> ></iqser-circle-button>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-download="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as download">
<div class="cell"> <div class="cell">
<div [class.no-bold]="download.lastDownload" class="table-item-title heading"> <div [class.no-bold]="download.lastDownload" class="table-item-title heading">
{{ download.filename }} {{ download.filename }}

View File

@ -1,22 +1,34 @@
import { Component, forwardRef, Injector, OnInit } from '@angular/core'; import { Component, forwardRef, Injector } from '@angular/core';
import { FileDownloadService } from '@upload-download/services/file-download.service'; import { FileDownloadService } from '@upload-download/services/file-download.service';
import { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper'; import { DownloadStatus } from '@upload-download/model/download-status';
import { DownloadControllerService } from '@redaction/red-ui-http'; import {
import { CircleButtonTypes, DefaultListingServices, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui'; CircleButtonTypes,
DefaultListingServicesTmp,
EntitiesService,
ListingComponent,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { timer } from 'rxjs';
import { RouterHistoryService } from '@services/router-history.service'; import { RouterHistoryService } from '@services/router-history.service';
@Component({ @Component({
selector: 'redaction-downloads-list-screen', selector: 'redaction-downloads-list-screen',
templateUrl: './downloads-list-screen.component.html', templateUrl: './downloads-list-screen.component.html',
styleUrls: ['./downloads-list-screen.component.scss'], styleUrls: ['./downloads-list-screen.component.scss'],
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DownloadsListScreenComponent) }], providers: [
...DefaultListingServicesTmp,
{ provide: EntitiesService, useExisting: FileDownloadService },
{
provide: ListingComponent,
useExisting: forwardRef(() => DownloadsListScreenComponent),
},
],
}) })
export class DownloadsListScreenComponent extends ListingComponent<DownloadStatusWrapper> implements OnInit { export class DownloadsListScreenComponent extends ListingComponent<DownloadStatus> {
readonly circleButtonTypes = CircleButtonTypes; readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('downloads-list.table-header.title'); readonly tableHeaderLabel = _('downloads-list.table-header.title');
readonly tableColumnConfigs: TableColumnConfig<DownloadStatusWrapper>[] = [ readonly tableColumnConfigs: TableColumnConfig<DownloadStatus>[] = [
{ label: _('downloads-list.table-col-names.name'), width: '2fr' }, { label: _('downloads-list.table-col-names.name'), width: '2fr' },
{ label: _('downloads-list.table-col-names.size') }, { label: _('downloads-list.table-col-names.size') },
{ label: _('downloads-list.table-col-names.date') }, { label: _('downloads-list.table-col-names.date') },
@ -28,37 +40,27 @@ export class DownloadsListScreenComponent extends ListingComponent<DownloadStatu
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
readonly fileDownloadService: FileDownloadService, readonly fileDownloadService: FileDownloadService,
readonly routerHistoryService: RouterHistoryService, readonly routerHistoryService: RouterHistoryService,
private readonly _downloadControllerService: DownloadControllerService,
) { ) {
super(_injector); super(_injector);
this._loadingService.loadWhile(this._loadData());
} }
async ngOnInit() { downloadItem(download: DownloadStatus) {
this._loadingService.start();
await this._loadData();
this.addSubscription = timer(0, 5000).subscribe(async () => {
await this._loadData();
});
this._loadingService.stop();
}
downloadItem(download: DownloadStatusWrapper) {
this._loadingService.loadWhile(this.fileDownloadService.performDownload(download)); this._loadingService.loadWhile(this.fileDownloadService.performDownload(download));
} }
deleteItems(downloads?: DownloadStatusWrapper[]) { deleteItems(downloads?: DownloadStatus[]) {
this._loadingService.loadWhile(this._deleteItems(downloads)); this._loadingService.loadWhile(this._deleteItems(downloads));
} }
private async _deleteItems(downloads?: DownloadStatusWrapper[]) { private async _deleteItems(downloads?: DownloadStatus[]) {
const storageIds = (downloads || this.listingService.selected).map(d => d.storageId); const storageIds = (downloads || this.listingService.selected).map(d => d.storageId);
await this._downloadControllerService.deleteDownload({ storageIds }).toPromise(); await this.fileDownloadService.delete({ storageIds }).toPromise();
this.listingService.setSelected([]); this.listingService.setSelected([]);
await this._loadData(); await this._loadData();
} }
private async _loadData() { private async _loadData() {
await this.fileDownloadService.getDownloadStatus().toPromise(); await this.fileDownloadService.loadAll().toPromise();
this.entitiesService.setEntities(this.fileDownloadService.downloads);
} }
} }

View File

@ -4,7 +4,6 @@ import { ProfileModel, UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { LanguageService } from '@i18n/language.service'; import { LanguageService } from '@i18n/language.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { UserControllerService } from '@redaction/red-ui-http';
import { ConfigService } from '@services/config.service'; import { ConfigService } from '@services/config.service';
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { languagesTranslations } from '../../translations/languages-translations'; import { languagesTranslations } from '../../translations/languages-translations';
@ -27,7 +26,6 @@ export class UserProfileScreenComponent implements OnInit {
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _configService: ConfigService, private readonly _configService: ConfigService,
private readonly _userControllerService: UserControllerService,
private readonly _languageService: LanguageService, private readonly _languageService: LanguageService,
private readonly _domSanitizer: DomSanitizer, private readonly _domSanitizer: DomSanitizer,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
@ -82,14 +80,14 @@ export class UserProfileScreenComponent implements OnInit {
const value = this.formGroup.value as ProfileModel; const value = this.formGroup.value as ProfileModel;
delete value.language; delete value.language;
await this._userControllerService await this._userService
.updateMyProfile({ .updateMyProfile({
...value, ...value,
}) })
.toPromise(); .toPromise();
await this._userService.loadCurrentUser(); await this._userService.loadCurrentUser();
await this._userService.loadAllUsers(); await this._userService.loadAll().toPromise();
} }
this._initializeForm(); this._initializeForm();

View File

@ -39,6 +39,8 @@ import { UserDetailsComponent } from './dialogs/add-edit-user-dialog/user-detail
import { AddEditDossierAttributeDialogComponent } from './dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component'; import { AddEditDossierAttributeDialogComponent } from './dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component';
import { DossierAttributesListingScreenComponent } from './screens/dossier-attributes-listing/dossier-attributes-listing-screen.component'; import { DossierAttributesListingScreenComponent } from './screens/dossier-attributes-listing/dossier-attributes-listing-screen.component';
import { TrashScreenComponent } from './screens/trash/trash-screen.component'; import { TrashScreenComponent } from './screens/trash/trash-screen.component';
import { AuditService } from './services/audit.service';
import { DigitalSignatureService } from './services/digital-signature.service';
const dialogs = [ const dialogs = [
AddEditDossierTemplateDialogComponent, AddEditDossierTemplateDialogComponent,
@ -88,7 +90,7 @@ const components = [
@NgModule({ @NgModule({
declarations: [...components], declarations: [...components],
providers: [AdminDialogService], providers: [AdminDialogService, AuditService, DigitalSignatureService],
imports: [CommonModule, SharedModule, AdminRoutingModule, NgxChartsModule, ColorPickerModule, MonacoEditorModule], imports: [CommonModule, SharedModule, AdminRoutingModule, NgxChartsModule, ColorPickerModule, MonacoEditorModule],
}) })
export class AdminModule {} export class AdminModule {}

View File

@ -2,7 +2,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { AppStateService } from '@state/app-state.service'; import { AppStateService } from '@state/app-state.service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -18,7 +17,7 @@ export class DossierTemplateActionsComponent implements OnInit {
readonly currentUser = this._userService.currentUser; readonly currentUser = this._userService.currentUser;
@Input() dossierTemplateId: string; @Input() dossierTemplateId: string;
@Output() loadDossierTemplatesData = new EventEmitter<any>(); @Output() readonly loadDossierTemplatesData = new EventEmitter<void>();
constructor( constructor(
private readonly _router: Router, private readonly _router: Router,
@ -26,9 +25,8 @@ export class DossierTemplateActionsComponent implements OnInit {
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
private readonly _dossierTemplateControllerService: DossierTemplateControllerService, private readonly _dossierTemplatesService: DossierTemplatesService,
) {} ) {}
get dossierTemplate() { get dossierTemplate() {
@ -41,7 +39,7 @@ export class DossierTemplateActionsComponent implements OnInit {
openEditDossierTemplateDialog($event: any) { openEditDossierTemplateDialog($event: any) {
this._dialogService.openDialog('addEditDossierTemplate', $event, this.dossierTemplate, () => { this._dialogService.openDialog('addEditDossierTemplate', $event, this.dossierTemplate, () => {
this.loadDossierTemplatesData?.emit(); this.loadDossierTemplatesData.emit();
}); });
} }
@ -49,8 +47,8 @@ export class DossierTemplateActionsComponent implements OnInit {
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', $event, null, async () => {
this._loadingService.start(); this._loadingService.start();
await this._dossierTemplateControllerService await this._dossierTemplatesService
.deleteDossierTemplates([this.dossierTemplateId]) .delete([this.dossierTemplateId])
.toPromise() .toPromise()
.catch(error => { .catch(error => {
if (error.status === 409) { if (error.status === 409) {
@ -60,12 +58,11 @@ export class DossierTemplateActionsComponent implements OnInit {
} }
this._loadingService.stop(); this._loadingService.stop();
}); });
await this._dossierTemplateControllerService.deleteDossierTemplates([this.dossierTemplateId]).toPromise();
await this._dossierTemplatesService.loadAll().toPromise(); await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
await this._router.navigate(['main', 'admin']); await this._router.navigate(['main', 'admin']);
this._loadingService.stop(); this._loadingService.stop();
this.loadDossierTemplatesData?.emit(); this.loadDossierTemplatesData.emit();
}); });
} }
} }

View File

@ -65,7 +65,7 @@ export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe impl
...this.dossierAttributeForm.getRawValue(), ...this.dossierAttributeForm.getRawValue(),
}; };
this._dossierAttributesService.addOrUpdateConfig(attribute).subscribe( this._dossierAttributesService.createOrUpdate(attribute).subscribe(
() => { () => {
this.dialogRef.close(true); this.dialogRef.close(true);
}, },

View File

@ -4,13 +4,12 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as moment from 'moment'; import * as moment from 'moment';
import { Moment } from 'moment'; import { Moment } from 'moment';
import { DossierTemplateControllerService, DownloadFileType, IDossierTemplate } from '@redaction/red-ui-http'; import { DownloadFileType, IDossierTemplate } from '@redaction/red-ui-http';
import { applyIntervalConstraints } from '@utils/date-inputs-utils'; import { applyIntervalConstraints } from '@utils/date-inputs-utils';
import { downloadTypesTranslations } from '../../../../translations/download-types-translations'; import { downloadTypesTranslations } from '../../../../translations/download-types-translations';
import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service';
@Component({ @Component({
selector: 'redaction-add-edit-dossier-template-dialog',
templateUrl: './add-edit-dossier-template-dialog.component.html', templateUrl: './add-edit-dossier-template-dialog.component.html',
styleUrls: ['./add-edit-dossier-template-dialog.component.scss'], styleUrls: ['./add-edit-dossier-template-dialog.component.scss'],
}) })
@ -31,7 +30,6 @@ export class AddEditDossierTemplateDialogComponent {
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _dossierTemplateController: DossierTemplateControllerService,
public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>, public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly dossierTemplate: IDossierTemplate, @Inject(MAT_DIALOG_DATA) readonly dossierTemplate: IDossierTemplate,
) { ) {
@ -99,7 +97,7 @@ export class AddEditDossierTemplateDialogComponent {
validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').value : null, validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').value : null,
validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null, validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null,
}; };
await this._dossierTemplateController.createOrUpdateDossierTemplate(dossierTemplate).toPromise(); await this._dossierTemplatesService.createOrUpdate(dossierTemplate).toPromise();
await this._dossierTemplatesService.loadAll().toPromise(); await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData(); await this._appStateService.loadDictionaryData();
this.dialogRef.close(true); this.dialogRef.close(true);

View File

@ -1,6 +1,5 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms'; import { FormBuilder, Validators } from '@angular/forms';
import { UserControllerService } from '@redaction/red-ui-http';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { LoadingService } from '@iqser/common-ui'; import { LoadingService } from '@iqser/common-ui';
import { User } from '@models/user'; import { User } from '@models/user';
@ -19,14 +18,13 @@ export class ResetPasswordComponent {
constructor( constructor(
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _userControllerService: UserControllerService,
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
) {} ) {}
async save() { async save() {
this._loadingService.start(); this._loadingService.start();
await this._userControllerService await this._userService
.resetPassword( .resetPassword(
{ {
password: this.passwordForm.get('temporaryPassword').value, password: this.passwordForm.get('temporaryPassword').value,

View File

@ -1,11 +1,11 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../../services/admin-dialog.service'; import { AdminDialogService } from '../../../services/admin-dialog.service';
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { rolesTranslations } from '../../../../../translations/roles-translations'; import { rolesTranslations } from '../../../../../translations/roles-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@models/user'; import { User } from '@models/user';
import { UserService } from '@services/user.service';
@Component({ @Component({
selector: 'redaction-user-details', selector: 'redaction-user-details',
@ -29,7 +29,7 @@ export class UserDetailsComponent implements OnInit {
private readonly _toaster: Toaster, private readonly _toaster: Toaster,
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _userControllerService: UserControllerService, private readonly _userService: UserService,
) {} ) {}
get changed(): boolean { get changed(): boolean {
@ -102,8 +102,8 @@ export class UserDetailsComponent implements OnInit {
const userData = { ...this.userForm.getRawValue(), roles: this.activeRoles }; const userData = { ...this.userForm.getRawValue(), roles: this.activeRoles };
if (!this.user) { if (!this.user) {
await this._userControllerService await this._userService
.createUser(userData) .create(userData)
.toPromise() .toPromise()
.then(() => { .then(() => {
this.closeDialog.emit(true); this.closeDialog.emit(true);
@ -117,7 +117,7 @@ export class UserDetailsComponent implements OnInit {
this._loadingService.stop(); this._loadingService.stop();
}); });
} else { } else {
await this._userControllerService.updateProfile(userData, this.user.id).toPromise(); await this._userService.updateProfile(userData, this.user.id).toPromise();
this.closeDialog.emit(true); this.closeDialog.emit(true);
} }
} }

View File

@ -1,10 +1,10 @@
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserControllerService } from '@redaction/red-ui-http'; import { List, LoadingService } from '@iqser/common-ui';
import { LoadingService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@models/user'; import { User } from '@models/user';
import { DossiersService } from '../../../dossier/services/dossiers.service'; import { DossiersService } from '../../../dossier/services/dossiers.service';
import { UserService } from '@services/user.service';
@Component({ @Component({
selector: 'redaction-confirm-delete-users-dialog', selector: 'redaction-confirm-delete-users-dialog',
@ -20,11 +20,11 @@ export class ConfirmDeleteUsersDialogComponent {
dossiersCount: number; dossiersCount: number;
constructor( constructor(
private readonly _dossiersService: DossiersService, private readonly _userService: UserService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _userControllerService: UserControllerService, private readonly _dossiersService: DossiersService,
@Inject(MAT_DIALOG_DATA) readonly users: List<User>,
readonly dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>, readonly dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly users: User[],
) { ) {
this.dossiersCount = this._dossiersService.all.filter(dw => { this.dossiersCount = this._dossiersService.all.filter(dw => {
for (const user of this.users) { for (const user of this.users) {
@ -43,7 +43,7 @@ export class ConfirmDeleteUsersDialogComponent {
async deleteUser() { async deleteUser() {
if (this.valid) { if (this.valid) {
this._loadingService.start(); this._loadingService.start();
await this._userControllerService.deleteUsers(this.users.map(u => u.id)).toPromise(); await this._userService.delete(this.users.map(u => u.id)).toPromise();
this.dialogRef.close(true); this.dialogRef.close(true);
} else { } else {
this.showToast = true; this.showToast = true;

View File

@ -53,8 +53,8 @@
</ng-container> </ng-container>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-field="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as field">
<div class="cell"> <div class="cell">
<iqser-editable-input <iqser-editable-input
(save)="field.name = $event" (save)="field.name = $event"

View File

@ -57,7 +57,7 @@
<mat-select-trigger> <mat-select-trigger>
<redaction-initials-avatar <redaction-initials-avatar
*ngIf="filterForm.get('userId').value !== ALL_USERS" *ngIf="filterForm.get('userId').value !== ALL_USERS"
[userId]="filterForm.get('userId').value" [user]="filterForm.get('userId').value"
[withName]="true" [withName]="true"
size="small" size="small"
></redaction-initials-avatar> ></redaction-initials-avatar>
@ -66,7 +66,7 @@
<mat-option *ngFor="let userId of userIds" [value]="userId"> <mat-option *ngFor="let userId of userIds" [value]="userId">
<redaction-initials-avatar <redaction-initials-avatar
*ngIf="userId !== ALL_USERS" *ngIf="userId !== ALL_USERS"
[userId]="userId" [user]="userId"
[withName]="true" [withName]="true"
size="small" size="small"
></redaction-initials-avatar> ></redaction-initials-avatar>
@ -97,8 +97,8 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-log="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as log">
<div class="cell"> <div class="cell">
{{ log.message }} {{ log.message }}
</div> </div>
@ -108,7 +108,7 @@
</div> </div>
<div class="user-column cell"> <div class="user-column cell">
<redaction-initials-avatar [userId]="log.userId" [withName]="true" size="small"></redaction-initials-avatar> <redaction-initials-avatar [user]="log.userId" [withName]="true" size="small"></redaction-initials-avatar>
</div> </div>
<div [translate]="translations[log.category]" class="cell"></div> <div [translate]="translations[log.category]" class="cell"></div>

View File

@ -1,6 +1,6 @@
import { Component, forwardRef, Injector, OnDestroy, OnInit } from '@angular/core'; import { Component, forwardRef, Injector, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { AuditControllerService, AuditResponse, AuditSearchRequest, IAudit } from '@redaction/red-ui-http'; import { AuditResponse, AuditSearchRequest, IAudit } from '@redaction/red-ui-http';
import { Moment } from 'moment'; import { Moment } from 'moment';
import { applyIntervalConstraints } from '@utils/date-inputs-utils'; import { applyIntervalConstraints } from '@utils/date-inputs-utils';
import { DefaultListingServices, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui'; import { DefaultListingServices, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui';
@ -8,6 +8,7 @@ import { auditCategoriesTranslations } from '../../translations/audit-categories
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { Audit } from '@models/audit.model'; import { Audit } from '@models/audit.model';
import { AuditService } from '../../services/audit.service';
const PAGE_SIZE = 50; const PAGE_SIZE = 50;
@ -41,7 +42,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnD
protected readonly _injector: Injector, protected readonly _injector: Injector,
private readonly _formBuilder: FormBuilder, private readonly _formBuilder: FormBuilder,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _auditControllerService: AuditControllerService, private readonly _auditService: AuditService,
) { ) {
super(_injector); super(_injector);
this.filterForm = this._formBuilder.group({ this.filterForm = this._formBuilder.group({
@ -102,8 +103,8 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnD
to, to,
}; };
promises.push(this._auditControllerService.getAuditCategories().toPromise()); promises.push(this._auditService.getCategories().toPromise());
promises.push(this._auditControllerService.searchAuditLog(logsRequestBody).toPromise()); promises.push(this._auditService.searchAuditLog(logsRequestBody).toPromise());
const data = await Promise.all(promises); const data = await Promise.all(promises);
this.categories = data[0].map(c => c.category); this.categories = data[0].map(c => c.category);

View File

@ -25,8 +25,8 @@
</div> </div>
</section> </section>
<ng-template #tableItemTemplate let-color="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as color">
<div class="cell"> <div class="cell">
<div [translate]="translations[color.key]" class="table-item-title heading"></div> <div [translate]="translations[color.key]" class="table-item-title heading"></div>
</div> </div>

View File

@ -77,8 +77,8 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-dict="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as dict">
<div class="cell"> <div class="cell">
<div [ngStyle]="{ 'background-color': dict.hexColor }" class="color-square"></div> <div [ngStyle]="{ 'background-color': dict.hexColor }" class="color-square"></div>
<div class="dict-name"> <div class="dict-name">

View File

@ -1,11 +1,12 @@
import { Component, OnDestroy } from '@angular/core'; import { Component, OnDestroy } from '@angular/core';
import { DigitalSignature, DigitalSignatureControllerService } from '@redaction/red-ui-http'; import { DigitalSignature } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { lastIndexOfEnd } from '@utils/functions'; import { lastIndexOfEnd } from '@utils/functions';
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { RouterHistoryService } from '@services/router-history.service'; import { RouterHistoryService } from '@services/router-history.service';
import { DigitalSignatureService } from '../../services/digital-signature.service';
@Component({ @Component({
selector: 'redaction-digital-signature-screen', selector: 'redaction-digital-signature-screen',
@ -27,7 +28,7 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
readonly routerHistoryService: RouterHistoryService, readonly routerHistoryService: RouterHistoryService,
private readonly _digitalSignatureControllerService: DigitalSignatureControllerService, private readonly _digitalSignatureService: DigitalSignatureService,
) { ) {
super(); super();
this.loadDigitalSignatureAndInitializeForm(); this.loadDigitalSignatureAndInitializeForm();
@ -45,8 +46,8 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
digitalSignature.password = digitalSignature.keySecret; digitalSignature.password = digitalSignature.keySecret;
const observable = this.digitalSignatureExists const observable = this.digitalSignatureExists
? this._digitalSignatureControllerService.updateDigitalSignature(digitalSignature) ? this._digitalSignatureService.update(digitalSignature)
: this._digitalSignatureControllerService.saveDigitalSignature(digitalSignature); : this._digitalSignatureService.save(digitalSignature);
this.addSubscription = observable.subscribe( this.addSubscription = observable.subscribe(
() => { () => {
@ -64,7 +65,7 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
} }
removeDigitalSignature() { removeDigitalSignature() {
this.addSubscription = this._digitalSignatureControllerService.deleteDigitalSignature().subscribe( this.addSubscription = this._digitalSignatureService.delete().subscribe(
() => { () => {
this.loadDigitalSignatureAndInitializeForm(); this.loadDigitalSignatureAndInitializeForm();
this._toaster.success(_('digital-signature-screen.action.delete-success')); this._toaster.success(_('digital-signature-screen.action.delete-success'));
@ -88,8 +89,8 @@ export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements
loadDigitalSignatureAndInitializeForm() { loadDigitalSignatureAndInitializeForm() {
this._loadingService.start(); this._loadingService.start();
this.addSubscription = this._digitalSignatureControllerService this.addSubscription = this._digitalSignatureService
.getDigitalSignature() .getSignature()
.subscribe( .subscribe(
digitalSignature => { digitalSignature => {
this.digitalSignatureExists = true; this.digitalSignatureExists = true;

View File

@ -64,8 +64,8 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-attribute="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as attribute">
<div class="cell"> <div class="cell">
{{ attribute.label }} {{ attribute.label }}
</div> </div>

View File

@ -1,7 +1,8 @@
import { Component, forwardRef, Injector, OnInit } from '@angular/core'; import { Component, forwardRef, Injector, OnInit } from '@angular/core';
import { import {
CircleButtonTypes, CircleButtonTypes,
DefaultListingServices, DefaultListingServicesTmp,
EntitiesService,
IconButtonTypes, IconButtonTypes,
ListingComponent, ListingComponent,
LoadingService, LoadingService,
@ -22,7 +23,8 @@ import { DossierTemplatesService } from '../../../dossier/services/dossier-templ
templateUrl: './dossier-attributes-listing-screen.component.html', templateUrl: './dossier-attributes-listing-screen.component.html',
styleUrls: ['./dossier-attributes-listing-screen.component.scss'], styleUrls: ['./dossier-attributes-listing-screen.component.scss'],
providers: [ providers: [
...DefaultListingServices, ...DefaultListingServicesTmp,
{ provide: EntitiesService, useExisting: DossierAttributesService },
{ provide: ListingComponent, useExisting: forwardRef(() => DossierAttributesListingScreenComponent) }, { provide: ListingComponent, useExisting: forwardRef(() => DossierAttributesListingScreenComponent) },
], ],
}) })
@ -59,7 +61,7 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', $event, null, async () => {
this._loadingService.start(); this._loadingService.start();
const ids = dossierAttribute ? [dossierAttribute.id] : this.listingService.selected.map(item => item.id); const ids = dossierAttribute ? [dossierAttribute.id] : this.listingService.selected.map(item => item.id);
await this._dossierAttributesService.deleteConfigs(ids); await this._dossierAttributesService.delete(ids).toPromise();
this.listingService.setSelected([]); this.listingService.setSelected([]);
await this._loadData(); await this._loadData();
}); });
@ -68,18 +70,14 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
openAddEditAttributeDialog($event: MouseEvent, dossierAttribute?: IDossierAttributeConfig) { openAddEditAttributeDialog($event: MouseEvent, dossierAttribute?: IDossierAttributeConfig) {
const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId;
this._dialogService.openDialog( this._dialogService.openDialog('addEditDossierAttribute', $event, { dossierAttribute, dossierTemplateId }, async () =>
'addEditDossierAttribute', this._loadData(),
$event,
{ dossierAttribute, dossierTemplateId },
async () => this._loadData(),
); );
} }
private async _loadData() { private async _loadData() {
this._loadingService.start(); this._loadingService.start();
const attributes = await this._dossierAttributesService.getConfig(); await this._dossierAttributesService.loadAll().toPromise();
this.entitiesService.setEntities(attributes);
this._loadingService.stop(); this._loadingService.stop();
} }
} }

View File

@ -38,7 +38,7 @@
<ng-template #actionsTemplate let-dossierTemplate="entity"> <ng-template #actionsTemplate let-dossierTemplate="entity">
<redaction-dossier-template-actions <redaction-dossier-template-actions
(loadDossierTemplatesData)="loadDossierTemplatesData()" (loadDossierTemplatesData)="loadDossierTemplateStats()"
[dossierTemplateId]="dossierTemplate.dossierTemplateId" [dossierTemplateId]="dossierTemplate.dossierTemplateId"
class="actions-container" class="actions-container"
></redaction-dossier-template-actions> ></redaction-dossier-template-actions>
@ -61,8 +61,8 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-dossierTemplate="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as dossierTemplate">
<div class="cell"> <div class="cell">
<div class="table-item-title heading"> <div class="table-item-title heading">
{{ dossierTemplate.name }} {{ dossierTemplate.name }}
@ -76,7 +76,7 @@
</div> </div>
<div class="cell user-column"> <div class="cell user-column">
<redaction-initials-avatar [userId]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [user]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar>
</div> </div>
<div class="cell small-label"> <div class="cell small-label">

View File

@ -13,7 +13,6 @@ import {
TableColumnConfig, TableColumnConfig,
Toaster, Toaster,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RouterHistoryService } from '@services/router-history.service'; import { RouterHistoryService } from '@services/router-history.service';
@ -42,22 +41,21 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
]; ];
constructor( constructor(
protected readonly _injector: Injector,
private readonly _toaster: Toaster, private readonly _toaster: Toaster,
protected readonly _injector: Injector,
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService, private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
readonly routerHistoryService: RouterHistoryService, readonly routerHistoryService: RouterHistoryService,
readonly userPreferenceService: UserPreferenceService, readonly userPreferenceService: UserPreferenceService,
private readonly _dossierTemplateControllerService: DossierTemplateControllerService, private readonly _dossierTemplatesService: DossierTemplatesService,
) { ) {
super(_injector); super(_injector);
} }
ngOnInit(): void { ngOnInit(): void {
this.loadDossierTemplatesData(); this.loadDossierTemplateStats();
} }
openBulkDeleteTemplatesDialog($event?: MouseEvent) { openBulkDeleteTemplatesDialog($event?: MouseEvent) {
@ -66,35 +64,13 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
}); });
} }
loadDossierTemplatesData() {
this._appStateService.reset();
this._loadDossierTemplateStats();
}
openAddDossierTemplateDialog() { openAddDossierTemplateDialog() {
this._dialogService.openDialog('addEditDossierTemplate', null, null, () => { this._dialogService.openDialog('addEditDossierTemplate', null, null, () => {
this.loadDossierTemplatesData(); this.loadDossierTemplateStats();
}); });
} }
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) { loadDossierTemplateStats() {
await this._dossierTemplateControllerService
.deleteDossierTemplates(templateIds)
.toPromise()
.catch(error => {
if (error.status === 409) {
this._toaster.error(_('dossier-templates-listing.error.conflict'));
} else {
this._toaster.error(_('dossier-templates-listing.error.generic'));
}
});
this.listingService.setSelected([]);
await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData();
this.loadDossierTemplatesData();
}
private _loadDossierTemplateStats() {
this.entitiesService.all.forEach(rs => { this.entitiesService.all.forEach(rs => {
const dictionaries = this._appStateService.dictionaryData[rs.dossierTemplateId]; const dictionaries = this._appStateService.dictionaryData[rs.dossierTemplateId];
if (dictionaries) { if (dictionaries) {
@ -107,4 +83,21 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
} }
}); });
} }
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) {
await this._dossierTemplatesService
.delete(templateIds)
.toPromise()
.catch(error => {
if (error.status === 409) {
this._toaster.error(_('dossier-templates-listing.error.conflict'));
} else {
this._toaster.error(_('dossier-templates-listing.error.generic'));
}
});
this.listingService.setSelected([]);
await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData();
this.loadDossierTemplateStats();
}
} }

View File

@ -74,8 +74,8 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-attribute="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as attribute">
<div class="label cell"> <div class="label cell">
<span>{{ attribute.label }}</span> <span>{{ attribute.label }}</span>
</div> </div>

View File

@ -41,7 +41,7 @@
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-entity="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as entity">
<div class="cell filename"> <div class="cell filename">
<div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above"> <div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above">
{{ entity.dossierName }} {{ entity.dossierName }}
@ -63,7 +63,7 @@
</div> </div>
<div class="cell user-column"> <div class="cell user-column">
<redaction-initials-avatar [userId]="entity.ownerId" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [user]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
</div> </div>
<div class="cell"> <div class="cell">

View File

@ -65,10 +65,10 @@
></iqser-circle-button> ></iqser-circle-button>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-user="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as user">
<div class="cell"> <div class="cell">
<redaction-initials-avatar [showYou]="true" [userId]="user.id" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [showYou]="true" [user]="user" [withName]="true"></redaction-initials-avatar>
</div> </div>
<div class="small-label cell">{{ user.email || '-' }}</div> <div class="small-label cell">{{ user.email || '-' }}</div>

View File

@ -1,19 +1,18 @@
import { Component, forwardRef, Injector, OnInit, QueryList, ViewChildren } from '@angular/core'; import { Component, forwardRef, Injector, OnInit } from '@angular/core';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component'; import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service'; import { TranslateChartService } from '@services/translate-chart.service';
import { import {
CircleButtonTypes, CircleButtonTypes,
DefaultListingServices, DefaultListingServicesTmp,
EntitiesService,
IconButtonTypes, IconButtonTypes,
ListingComponent, ListingComponent,
LoadingService, LoadingService,
TableColumnConfig, TableColumnConfig,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { rolesTranslations } from '../../../../translations/roles-translations'; import { rolesTranslations } from '../../../../translations/roles-translations';
@ -23,7 +22,14 @@ import { User } from '@models/user';
@Component({ @Component({
templateUrl: './user-listing-screen.component.html', templateUrl: './user-listing-screen.component.html',
styleUrls: ['./user-listing-screen.component.scss'], styleUrls: ['./user-listing-screen.component.scss'],
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => UserListingScreenComponent) }], providers: [
...DefaultListingServicesTmp,
{ provide: EntitiesService, useExisting: UserService },
{
provide: ListingComponent,
useExisting: forwardRef(() => UserListingScreenComponent),
},
],
}) })
export class UserListingScreenComponent extends ListingComponent<User> implements OnInit { export class UserListingScreenComponent extends ListingComponent<User> implements OnInit {
readonly translations = rolesTranslations; readonly translations = rolesTranslations;
@ -40,8 +46,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
]; ];
collapsedDetails = false; collapsedDetails = false;
chartData: DoughnutChartConfig[] = []; chartData: DoughnutChartConfig[] = [];
@ViewChildren(InitialsAvatarComponent)
private readonly _avatars: QueryList<InitialsAvatarComponent>;
constructor( constructor(
readonly userService: UserService, readonly userService: UserService,
@ -49,7 +53,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _dialogService: AdminDialogService, private readonly _dialogService: AdminDialogService,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
private readonly _userControllerService: UserControllerService,
private readonly _translateChartService: TranslateChartService, private readonly _translateChartService: TranslateChartService,
) { ) {
super(_injector); super(_injector);
@ -87,9 +90,8 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
async toggleActive(user: User) { async toggleActive(user: User) {
this._loadingService.start(); this._loadingService.start();
const requestBody = { ...user, roles: user.isActive ? [] : ['RED_USER'] }; const requestBody = { ...user, roles: user.isActive ? [] : ['RED_USER'] };
await this._userControllerService.updateProfile(requestBody, user.id).toPromise(); await this.userService.updateProfile(requestBody, user.id).toPromise();
await this._loadData(); await this._loadData();
this._avatars.find(item => item.userId === user.id).detectChanges();
} }
bulkDelete() { bulkDelete() {
@ -97,7 +99,7 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
} }
private async _loadData() { private async _loadData() {
this.entitiesService.setEntities(await this.userService.loadAllUsers()); await this.userService.loadAll().toPromise();
this._computeStats(); this._computeStats();
this._loadingService.stop(); this._loadingService.stop();
} }

View File

@ -0,0 +1,20 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { AuditResponse, AuditSearchRequest, CategoryModel, IAudit } from '@redaction/red-ui-http';
import { Observable } from 'rxjs';
@Injectable()
export class AuditService extends GenericService<IAudit> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'audit');
}
getCategories(): Observable<CategoryModel[]> {
return super.getAll<CategoryModel[]>(`${this._defaultModelPath}/categories`);
}
@Validate()
searchAuditLog(@RequiredParam() body: AuditSearchRequest): Observable<AuditResponse> {
return this._post(body, `${this._defaultModelPath}/search`);
}
}

View File

@ -0,0 +1,29 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
import { DigitalSignature, DigitalSignatureViewModel } from '@redaction/red-ui-http';
import { Observable } from 'rxjs';
@Injectable()
export class DigitalSignatureService extends GenericService<DigitalSignatureViewModel> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'digital-signature');
}
@Validate()
update(@RequiredParam() body: DigitalSignatureViewModel): Observable<unknown> {
return this._put(body);
}
@Validate()
save(@RequiredParam() body: DigitalSignature): Observable<DigitalSignatureViewModel> {
return this._post(body);
}
delete(): Observable<unknown> {
return super.delete({});
}
getSignature(): Observable<DigitalSignatureViewModel> {
return super.getAll();
}
}

View File

@ -36,8 +36,8 @@
<pre *ngIf="selectedReviewersList.length === 0" [innerHTML]="'assign-dossier-owner.dialog.no-reviewers' | translate" class="info"></pre> <pre *ngIf="selectedReviewersList.length === 0" [innerHTML]="'assign-dossier-owner.dialog.no-reviewers' | translate" class="info"></pre>
<iqser-input-with-action <iqser-input-with-action
[(value)]="searchQuery"
(valueChange)="setMembersSelectOptions()" (valueChange)="setMembersSelectOptions()"
[(value)]="searchQuery"
[placeholder]="'assign-dossier-owner.dialog.search' | translate" [placeholder]="'assign-dossier-owner.dialog.search' | translate"
[width]="560" [width]="560"
class="search-container" class="search-container"
@ -49,7 +49,7 @@
*ngFor="let userId of membersSelectOptions" *ngFor="let userId of membersSelectOptions"
[class.selected]="isMemberSelected(userId)" [class.selected]="isMemberSelected(userId)"
> >
<redaction-initials-avatar [userId]="userId" [withName]="true" size="large"></redaction-initials-avatar> <redaction-initials-avatar [user]="userId" [withName]="true" size="large"></redaction-initials-avatar>
<div class="actions"> <div class="actions">
<div (click)="toggleApprover(userId, $event)" *ngIf="!isOwner(userId)" class="make-approver"> <div (click)="toggleApprover(userId, $event)" *ngIf="!isOwner(userId)" class="make-approver">
<iqser-round-checkbox [active]="isApprover(userId)" class="mr-8"></iqser-round-checkbox> <iqser-round-checkbox [active]="isApprover(userId)" class="mr-8"></iqser-round-checkbox>

View File

@ -68,7 +68,7 @@ export class EditDossierAttributesComponent implements EditDossierSectionInterfa
dossierAttributeId: attr.id, dossierAttributeId: attr.id,
value: this.currentAttrValue(attr), value: this.currentAttrValue(attr),
})); }));
await this._dossierAttributesService.setValues(this.dossier, dossierAttributeList); await this._dossierAttributesService.setAttributes(this.dossier, dossierAttributeList).toPromise();
await this._loadAttributes(); await this._loadAttributes();
this.updateDossier.emit(); this.updateDossier.emit();
this._loadingService.stop(); this._loadingService.stop();
@ -134,7 +134,7 @@ export class EditDossierAttributesComponent implements EditDossierSectionInterfa
} }
private async _loadAttributes() { private async _loadAttributes() {
this.attributes = await this._dossierAttributesService.getValues(this.dossier); this.attributes = await this._dossierAttributesService.getWithValues(this.dossier);
this.customAttributes = this.attributes.filter(attr => !this.isImage(attr)); this.customAttributes = this.attributes.filter(attr => !this.isImage(attr));
this.imageAttributes = this.attributes.filter(attr => this.isImage(attr)); this.imageAttributes = this.attributes.filter(attr => this.isImage(attr));
} }

View File

@ -34,8 +34,8 @@
></iqser-circle-button> ></iqser-circle-button>
</ng-template> </ng-template>
<ng-template #tableItemTemplate let-file="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as file">
<div class="cell filename"> <div class="cell filename">
<span>{{ file.filename }}</span> <span>{{ file.filename }}</span>
</div> </div>

View File

@ -26,7 +26,6 @@ import { AnnotationProcessingService } from './services/annotation-processing.se
import { EditDossierDialogComponent } from './dialogs/edit-dossier-dialog/edit-dossier-dialog.component'; import { EditDossierDialogComponent } from './dialogs/edit-dossier-dialog/edit-dossier-dialog.component';
import { EditDossierGeneralInfoComponent } from './dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component'; import { EditDossierGeneralInfoComponent } from './dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component';
import { EditDossierDownloadPackageComponent } from './dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component'; import { EditDossierDownloadPackageComponent } from './dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component';
import { UserPreferenceControllerService } from '@redaction/red-ui-http';
import { EditDossierDictionaryComponent } from './dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component'; import { EditDossierDictionaryComponent } from './dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component';
import { EditDossierTeamMembersComponent } from './dialogs/edit-dossier-dialog/team-members/edit-dossier-team-members.component'; import { EditDossierTeamMembersComponent } from './dialogs/edit-dossier-dialog/team-members/edit-dossier-team-members.component';
import { TeamMembersManagerComponent } from './components/team-members-manager/team-members-manager.component'; import { TeamMembersManagerComponent } from './components/team-members-manager/team-members-manager.component';
@ -85,7 +84,6 @@ const services = [
PdfViewerDataService, PdfViewerDataService,
AnnotationDrawService, AnnotationDrawService,
AnnotationProcessingService, AnnotationProcessingService,
UserPreferenceControllerService,
]; ];
@NgModule({ @NgModule({

View File

@ -15,7 +15,7 @@
<div class="all-caps-label" translate="dossier-details.owner"></div> <div class="all-caps-label" translate="dossier-details.owner"></div>
<div class="mt-12 d-flex"> <div class="mt-12 d-flex">
<ng-container *ngIf="!editingOwner; else editOwner"> <ng-container *ngIf="!editingOwner; else editOwner">
<redaction-initials-avatar [userId]="owner?.id" [withName]="true" color="gray" size="large"></redaction-initials-avatar> <redaction-initials-avatar [user]="owner" [withName]="true" color="gray" size="large"></redaction-initials-avatar>
<iqser-circle-button <iqser-circle-button
(action)="editingOwner = true" (action)="editingOwner = true"

View File

@ -46,7 +46,7 @@ export class DossierDetailsComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.owner = this._userService.getRedUserById(this.dossiersService.activeDossier.ownerId); this.owner = this._userService.find(this.dossiersService.activeDossier.ownerId);
this.calculateChartConfig(); this.calculateChartConfig();
this.appStateService.fileChanged$.subscribe(() => { this.appStateService.fileChanged$.subscribe(() => {
this.calculateChartConfig(); this.calculateChartConfig();
@ -75,7 +75,7 @@ export class DossierDetailsComponent implements OnInit {
} }
async assignOwner(user: User | string) { async assignOwner(user: User | string) {
this.owner = typeof user === 'string' ? this._userService.getRedUserById(user) : user; this.owner = typeof user === 'string' ? this._userService.find(user) : user;
const activeDossier = this.dossiersService.activeDossier; const activeDossier = this.dossiersService.activeDossier;
const dossierRequest: DossierRequest = { ...activeDossier, dossierId: activeDossier.dossierId, ownerId: this.owner.id }; const dossierRequest: DossierRequest = { ...activeDossier, dossierId: activeDossier.dossierId, ownerId: this.owner.id };
await this.dossiersService.createOrUpdate(dossierRequest).toPromise(); await this.dossiersService.createOrUpdate(dossierRequest).toPromise();

View File

@ -34,7 +34,7 @@
</div> </div>
<div *ngIf="!file.isError" class="user-column cell"> <div *ngIf="!file.isError" class="user-column cell">
<redaction-initials-avatar [userId]="file.currentReviewer" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [user]="file.currentReviewer" [withName]="true"></redaction-initials-avatar>
</div> </div>
<div *ngIf="!file.isError" class="cell"> <div *ngIf="!file.isError" class="cell">

View File

@ -121,8 +121,8 @@
></redaction-table-item> ></redaction-table-item>
</ng-template> </ng-template>
<ng-template #workflowItemTemplate let-file="entity"> <ng-template #workflowItemTemplate let-entity="entity">
<div class="workflow-item"> <div *ngIf="cast(entity) as file" class="workflow-item">
<div> <div>
<div class="details"> <div class="details">
<div [matTooltip]="file.filename" class="filename" matTooltipPosition="above"> <div [matTooltip]="file.filename" class="filename" matTooltipPosition="above">
@ -131,7 +131,7 @@
<ng-container *ngTemplateOutlet="statsTemplate; context: { entity: file }"></ng-container> <ng-container *ngTemplateOutlet="statsTemplate; context: { entity: file }"></ng-container>
</div> </div>
<div class="user"> <div class="user">
<redaction-initials-avatar [userId]="file.currentReviewer"></redaction-initials-avatar> <redaction-initials-avatar [user]="file.currentReviewer"></redaction-initials-avatar>
</div> </div>
</div> </div>
<redaction-file-actions <redaction-file-actions
@ -143,15 +143,15 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #statsTemplate let-file="entity"> <ng-template #statsTemplate let-entity="entity">
<div class="small-label stats-subtitle"> <div *ngIf="cast(entity) as file" class="small-label stats-subtitle">
<div> <div>
<mat-icon svgIcon="red:pages"></mat-icon> <mat-icon svgIcon="red:pages"></mat-icon>
{{ file.numberOfPages }} {{ file.numberOfPages }}
</div> </div>
<div> <div>
<mat-icon svgIcon="red:exclude-pages"></mat-icon> <mat-icon svgIcon="red:exclude-pages"></mat-icon>
{{ file.excludedPagesCount }} {{ file.excludedPages.length }}
</div> </div>
<div *ngIf="file.lastOCRTime" [matTooltipPosition]="'above'" [matTooltip]="'dossier-overview.ocr-performed' | translate"> <div *ngIf="file.lastOCRTime" [matTooltipPosition]="'above'" [matTooltip]="'dossier-overview.ocr-performed' | translate">
<mat-icon svgIcon="red:ocr"></mat-icon> <mat-icon svgIcon="red:ocr"></mat-icon>

View File

@ -165,7 +165,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
.pipe(tap(index => (this._lastScrolledIndex = index))) .pipe(tap(index => (this._lastScrolledIndex = index)))
.subscribe(); .subscribe();
this.dossierAttributes = await this._dossierAttributesService.getValues(this.currentDossier); this.dossierAttributes = await this._dossierAttributesService.getWithValues(this.currentDossier);
} catch (e) { } catch (e) {
console.log('Error from dossier overview screen: ', e); console.log('Error from dossier overview screen: ', e);
} finally { } finally {

View File

@ -5,7 +5,7 @@
<redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge> <redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge>
</div> </div>
<div class="cell user-column"> <div class="cell user-column">
<redaction-initials-avatar [userId]="dossier.ownerId" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [user]="dossier.ownerId" [withName]="true"></redaction-initials-avatar>
</div> </div>
<div class="cell status-container"> <div class="cell status-container">
<redaction-dossiers-listing-actions (actionPerformed)="calculateData.emit()" [dossier]="dossier"></redaction-dossiers-listing-actions> <redaction-dossiers-listing-actions (actionPerformed)="calculateData.emit()" [dossier]="dossier"></redaction-dossiers-listing-actions>

View File

@ -42,7 +42,7 @@
<redaction-initials-avatar <redaction-initials-avatar
*ngIf="!editingReviewer" *ngIf="!editingReviewer"
[userId]="currentReviewer" [user]="currentReviewer"
[withName]="!!currentReviewer" [withName]="!!currentReviewer"
tooltipPosition="below" tooltipPosition="below"
></redaction-initials-avatar> ></redaction-initials-avatar>
@ -83,7 +83,7 @@
<ng-container *ngIf="permissionsService.isApprover() && !!lastReviewer"> <ng-container *ngIf="permissionsService.isApprover() && !!lastReviewer">
<div class="vertical-line"></div> <div class="vertical-line"></div>
<div class="all-caps-label mr-16 ml-8" translate="file-preview.last-reviewer"></div> <div class="all-caps-label mr-16 ml-8" translate="file-preview.last-reviewer"></div>
<redaction-initials-avatar [userId]="lastReviewer" [withName]="true"></redaction-initials-avatar> <redaction-initials-avatar [user]="lastReviewer" [withName]="true"></redaction-initials-avatar>
</ng-container> </ng-container>
<div class="vertical-line"></div> <div class="vertical-line"></div>

View File

@ -28,7 +28,7 @@ import { PermissionsService } from '@services/permissions.service';
import { timer } from 'rxjs'; import { timer } from 'rxjs';
import { UserPreferenceService } from '@services/user-preference.service'; import { UserPreferenceService } from '@services/user-preference.service';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { FileManagementControllerService, FileStatus, List, UserPreferenceControllerService } from '@redaction/red-ui-http'; import { FileManagementControllerService, FileStatus, List } from '@redaction/red-ui-http';
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service'; import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
import { download } from '@utils/file-download-utils'; import { download } from '@utils/file-download-utils';
import { ViewMode } from '@models/file/view-mode'; import { ViewMode } from '@models/file/view-mode';
@ -88,7 +88,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
readonly permissionsService: PermissionsService, readonly permissionsService: PermissionsService,
readonly userPreferenceService: UserPreferenceService, readonly userPreferenceService: UserPreferenceService,
readonly userService: UserService, readonly userService: UserService,
private readonly _userPreferenceControllerService: UserPreferenceControllerService,
private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _activatedRoute: ActivatedRoute, private readonly _activatedRoute: ActivatedRoute,
private readonly _dialogService: DossiersDialogService, private readonly _dialogService: DossiersDialogService,

View File

@ -21,8 +21,8 @@
</div> </div>
</section> </section>
<ng-template #tableItemTemplate let-item="entity"> <ng-template #tableItemTemplate let-entity="entity">
<div> <div *ngIf="cast(entity) as item">
<div class="cell filename"> <div class="cell filename">
<div [matTooltip]="item.filename" class="table-item-title heading" matTooltipPosition="above"> <div [matTooltip]="item.filename" class="table-item-title heading" matTooltipPosition="above">
<span <span

View File

@ -1,4 +1,4 @@
import { EntitiesService } from '@iqser/common-ui'; import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
import { DossierTemplate } from '@models/file/dossier-template'; import { DossierTemplate } from '@models/file/dossier-template';
import { IDossierTemplate } from '@redaction/red-ui-http'; import { IDossierTemplate } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
@ -59,4 +59,13 @@ export class DossierTemplatesService extends EntitiesService<DossierTemplate, ID
map(() => this.all), map(() => this.all),
); );
} }
delete(body: List): Observable<unknown> {
return super.delete(body, `${this._defaultModelPath}/delete`);
}
@Validate()
createOrUpdate(@RequiredParam() body: IDossierTemplate) {
return this._post(body);
}
} }

View File

@ -27,5 +27,5 @@
</div> </div>
<ng-template #avatar let-userId="userId"> <ng-template #avatar let-userId="userId">
<redaction-initials-avatar [userId]="userId" [withName]="true" color="gray" size="small"></redaction-initials-avatar> <redaction-initials-avatar [user]="userId" [withName]="true" color="gray" size="small"></redaction-initials-avatar>
</ng-template> </ng-template>

View File

@ -45,7 +45,10 @@ export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestr
downloadFiles($event: MouseEvent) { downloadFiles($event: MouseEvent) {
$event.stopPropagation(); $event.stopPropagation();
this.addSubscription = this._fileDownloadService this.addSubscription = this._fileDownloadService
.downloadFiles(this.files, this.dossier) .downloadFiles(
this.files.map(f => f.fileId),
this.dossier.dossierId,
)
.subscribe(() => this._toaster.info(_('download-status.queued'))); .subscribe(() => this._toaster.info(_('download-status.queued')));
} }
} }

View File

@ -1,5 +1,5 @@
<button [class.overlay]="showDot" mat-button> <button [class.overlay]="showDot" mat-button>
<redaction-initials-avatar [userId]="userId" [withName]="true" size="small"></redaction-initials-avatar> <redaction-initials-avatar [user]="userId" [withName]="true" size="small"></redaction-initials-avatar>
<mat-icon svgIcon="iqser:arrow-down"></mat-icon> <mat-icon svgIcon="iqser:arrow-down"></mat-icon>
</button> </button>
<div *ngIf="showDot" class="dot"></div> <div *ngIf="showDot" class="dot"></div>

View File

@ -1,12 +1,12 @@
<div class="wrapper"> <div *ngIf="_user && _user | name: namePipeOptions as userName" class="wrapper">
<div <div
[className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')" [className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')"
[matTooltipPosition]="tooltipPosition" [matTooltipPosition]="tooltipPosition"
[matTooltip]="displayName || ('initials-avatar.unassigned' | translate)" [matTooltip]="userName"
> >
{{ initials }} {{ _user | name: { showInitials: true, defaultValue: ('initials-avatar.unassigned' | translate) } }}
</div> </div>
<div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username"> <div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username">
{{ displayName || ('initials-avatar.unassigned' | translate) }} {{ userName }}
</div> </div>
</div> </div>

View File

@ -1,8 +1,9 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy } from '@angular/core'; import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { TranslateService } from '@ngx-translate/core';
import { AutoUnsubscribe } from '@iqser/common-ui'; import { AutoUnsubscribe } from '@iqser/common-ui';
import { User } from '@models/user'; import { User } from '@models/user';
import { TranslateService } from '@ngx-translate/core';
import { NamePipeOptions } from '@shared/pipes/name.pipe';
@Component({ @Component({
selector: 'redaction-initials-avatar', selector: 'redaction-initials-avatar',
@ -11,39 +12,47 @@ import { User } from '@models/user';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy { export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy {
@Input() userId: string;
@Input() color = 'lightgray'; @Input() color = 'lightgray';
@Input() size: 'small' | 'large' = 'small'; @Input() size: 'small' | 'large' = 'small';
@Input() withName = false; @Input() withName = false;
@Input() showYou = false; @Input() showYou = false;
@Input() tooltipPosition: 'below' | 'above' = 'above'; @Input() tooltipPosition: 'below' | 'above' = 'above';
displayName: string;
initials: string;
colorClass: string; colorClass: string;
user: User;
constructor( readonly namePipeOptions: NamePipeOptions = {
private readonly _userService: UserService, showYou: this.showYou,
private readonly _translateService: TranslateService, defaultValue: this._translateService.instant('initials-avatar.unassigned'),
private readonly _changeDetectorRef: ChangeDetectorRef, };
) {
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {
super(); super();
this.addSubscription = _userService.usersReloaded$.subscribe(() => { }
this.detectChanges();
}); _user: User;
@Input()
set user(user: User | string) {
if (typeof user === 'string') {
this._user = this._userService.find(user);
} else {
this._user = user;
}
} }
get hasBorder(): boolean { get hasBorder(): boolean {
return !!this.user && !this._isCurrentUser && this.user.isManager; return !!this._user && !this.isCurrentUser && this._user.isManager;
} }
get disabled(): boolean { get disabled(): boolean {
return this.user && !this.user.isActive; return this._user && !this._user.isActive;
}
get isCurrentUser(): boolean {
return this._userService.currentUser.id === this._user?.id;
} }
private get _colorClass() { private get _colorClass() {
if (this._isCurrentUser) { if (this.isCurrentUser) {
return 'primary-white'; return 'primary-white';
} }
if (this.disabled) { if (this.disabled) {
@ -56,44 +65,13 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange
return `${this.color}-dark`; return `${this.color}-dark`;
} }
private get _isCurrentUser(): boolean {
return this._userService.currentUser.id === this.user?.id;
}
ngOnChanges(): void { ngOnChanges(): void {
const isSystemUser = this.userId?.toLowerCase() === 'system'; const isSystemUser = this._user?.id?.toLowerCase() === 'system';
if (isSystemUser) { if (isSystemUser) {
this.displayName = 'System';
this.initials = 'SY';
this.colorClass = 'primary-white primary'; this.colorClass = 'primary-white primary';
return; return;
} }
this.user = this._userService.getUserById(this.userId);
this.displayName = this._userService.getNameForId(this.userId);
this.initials = this._getInitials();
this.colorClass = this._colorClass; this.colorClass = this._colorClass;
if (this.showYou && this._isCurrentUser) {
this.displayName += ` (${this._translateService.instant('initials-avatar.you')})`;
}
}
detectChanges(): void {
this.ngOnChanges();
this._changeDetectorRef.detectChanges();
}
private _getInitials(): string {
if (!this.displayName) {
return '?';
}
return this.displayName
.split(' ')
.filter((value, idx) => idx < 2 && value !== ' ')
.map(str => str[0])
.join('');
} }
} }

View File

@ -6,7 +6,7 @@
[class.large-spacing]="largeSpacing" [class.large-spacing]="largeSpacing"
class="member" class="member"
> >
<redaction-initials-avatar [userId]="userId" color="gray" size="large"></redaction-initials-avatar> <redaction-initials-avatar [user]="userId" color="gray" size="large"></redaction-initials-avatar>
<div *ngIf="canRemoveMember(userId)" class="remove"> <div *ngIf="canRemoveMember(userId)" class="remove">
<mat-icon svgIcon="iqser:close"></mat-icon> <mat-icon svgIcon="iqser:close"></mat-icon>
</div> </div>

View File

@ -3,16 +3,61 @@ import { UserService } from '@services/user.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { User } from '@models/user'; import { User } from '@models/user';
function getInitials(name: string) {
if (name.toLowerCase() === 'system') {
return 'SY';
}
const splittedName = name.split(' ').filter(value => value !== ' ' && value !== '');
return splittedName
.filter((value, index) => index < 2)
.map(str => str[0])
.join('');
}
function isSystemUser(user: User | string) {
const userId = typeof user === 'string' ? user : user.id;
return userId.toLowerCase() === 'system';
}
export interface NamePipeOptions {
showYou?: boolean;
showInitials?: boolean;
defaultValue?: string;
}
@Pipe({ @Pipe({
name: 'name', name: 'name',
}) })
export class NamePipe implements PipeTransform { export class NamePipe implements PipeTransform {
private readonly _defaultOptions: NamePipeOptions = { defaultValue: this._translateService.instant('unknown') };
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {} constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {}
transform(value: User | string): string { transform(value?: User | string, options = this._defaultOptions): string {
if (typeof value === 'string') { let name;
return this._userService.getNameForId(value) || this._translateService.instant('unknown'); if (!value || !isSystemUser(value)) {
name = this._getName(value) || options?.defaultValue;
} else {
name = 'System';
} }
return value.name;
if (options?.showYou && this._isCurrentUser(value)) {
name = `${name} (${this._translateService.instant('initials-avatar.you')})`;
}
return options?.showInitials ? getInitials(name) : name;
}
private _isCurrentUser(user: User | string): boolean {
const userId = typeof user === 'string' ? user : user.id;
return this._userService.currentUser.id === userId;
}
private _getName(user: User | string): string | undefined {
if (!user) {
return undefined;
}
return typeof user === 'string' ? this._userService.getNameForId(user) : user.name;
} }
} }

View File

@ -1,50 +1,67 @@
import { Injectable } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { DossierAttribute, DossierAttributes, DossierAttributesControllerService, IDossierAttributeConfig } from '@redaction/red-ui-http'; import { DossierAttribute, DossierAttributes, DossierAttributesConfig, IDossierAttributeConfig } from '@redaction/red-ui-http';
import { Dossier } from '@state/model/dossier'; import { Dossier } from '@state/model/dossier';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model'; import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { DossierAttributeConfig } from '@state/model/dossier-attribute-config'; import { DossierAttributeConfig } from '@state/model/dossier-attribute-config';
import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service';
import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui';
import { map, tap } from 'rxjs/operators';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class DossierAttributesService { export class DossierAttributesService extends EntitiesService<DossierAttributeConfig, IDossierAttributeConfig> {
constructor( constructor(private readonly _dossierTemplatesService: DossierTemplatesService, protected readonly _injector: Injector) {
private readonly _dossierAttributesControllerService: DossierAttributesControllerService, super(_injector, DossierAttributeConfig, 'dossier-attributes');
private readonly _dossierTemplatesService: DossierTemplatesService, }
) {}
async getValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> { async getWithValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> {
const attributes = await this._dossierAttributesControllerService.getDossierAttributes(dossier.id).toPromise(); const attributes = await this.getAttributes(dossier.id).toPromise();
const attributesConfig = await this._dossierAttributesControllerService const attributesConfig = await this.getConfig(dossier.dossierTemplateId).toPromise();
.getDossierAttributesConfig(dossier.dossierTemplateId)
.toPromise();
return attributesConfig.dossierAttributeConfigs.map(config => ({ return attributesConfig.map(config => ({
...config, ...config,
value: attributes.dossierAttributeList.find(attr => attr.dossierAttributeConfigId === config.id)?.value, value: attributes.find(attr => attr.dossierAttributeConfigId === config.id)?.value,
})); }));
} }
setValues(dossier: Dossier, dossierAttributeList: DossierAttribute[]): Promise<DossierAttributes> { @Validate()
return this._dossierAttributesControllerService.setDossierAttributes({ dossierAttributeList }, dossier.id).toPromise(); setAttributes(
@RequiredParam() dossier: Dossier,
@RequiredParam() dossierAttributeList: List<DossierAttribute>,
): Observable<DossierAttributes> {
return this._post({ dossierAttributeList }, `${this._defaultModelPath}/set/${dossier.id}`);
} }
deleteConfigs(ids: string[], dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Promise<void> { @Validate()
return this._dossierAttributesControllerService.deleteDossierAttributesConfig(ids, dossierTemplateId).toPromise(); delete(@RequiredParam() ids: List, dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Observable<unknown> {
return this._post(ids, `${this._defaultModelPath}/config/delete/${dossierTemplateId}`);
} }
async getConfig(dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Promise<DossierAttributeConfig[]> { loadAll(dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Observable<DossierAttributeConfig[]> {
const config$ = this._dossierAttributesControllerService.getDossierAttributesConfig(dossierTemplateId); return this.getConfig(dossierTemplateId).pipe(
const result = (await config$.toPromise())?.dossierAttributeConfigs || []; map(entities => entities ?? []),
return result.map(item => new DossierAttributeConfig(item)); mapEach(entity => new DossierAttributeConfig(entity)),
tap(entities => this.setEntities(entities)),
);
} }
addOrUpdateConfig( @Validate()
attribute: IDossierAttributeConfig, createOrUpdate(
@RequiredParam() attributeConfig: IDossierAttributeConfig,
dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId, dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId,
): Observable<IDossierAttributeConfig> { ): Observable<IDossierAttributeConfig> {
return this._dossierAttributesControllerService.addOrUpdateDossierAttributesConfig(attribute, dossierTemplateId); return this._post(attributeConfig, `${this._defaultModelPath}/config/${dossierTemplateId}`);
}
@Validate()
getConfig(@RequiredParam() dossierTemplateId: string): Observable<List<IDossierAttributeConfig>> {
return this._getOne<DossierAttributesConfig>(['config', dossierTemplateId]).pipe(map(res => res.dossierAttributeConfigs));
}
@Validate()
getAttributes(@RequiredParam() dossierId: string): Observable<List<DossierAttribute>> {
return this._getOne<DossierAttributes>([dossierId]).pipe(map(res => res.dossierAttributeList));
} }
} }

View File

@ -0,0 +1,50 @@
import { DownloadFileType, DownloadStatusType, IDownloadStatus, List } from '@redaction/red-ui-http';
import { IListable } from '@iqser/common-ui';
export class DownloadStatus implements IDownloadStatus, IListable {
readonly creationDate?: string;
readonly dossierId?: string;
readonly downloadFileTypes?: List<DownloadFileType>;
readonly fileIds?: List;
readonly fileSize?: number;
readonly filename?: string;
readonly lastDownload?: string;
readonly mimeType?: string;
readonly status?: DownloadStatusType;
readonly storageId?: string;
readonly userId?: string;
readonly size?: string;
inProgress: boolean;
constructor(downloadStatus: IDownloadStatus) {
this.creationDate = downloadStatus.creationDate;
this.dossierId = downloadStatus.dossierId;
this.downloadFileTypes = downloadStatus.downloadFileTypes;
this.fileIds = downloadStatus.fileIds;
this.fileSize = downloadStatus.fileSize;
this.filename = downloadStatus.filename;
this.lastDownload = downloadStatus.lastDownload;
this.mimeType = downloadStatus.mimeType;
this.status = downloadStatus.status;
this.storageId = downloadStatus.storageId;
this.userId = downloadStatus.userId;
this.size = this._size;
}
get id() {
return this.storageId;
}
get searchKey(): string {
return this.storageId;
}
get isReady() {
return this.status === 'READY';
}
private get _size() {
const i = this.fileSize === 0 ? 0 : Math.floor(Math.log(this.fileSize) / Math.log(1024));
return (this.fileSize / Math.pow(1024, i)).toFixed(2) + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}
}

View File

@ -1,53 +0,0 @@
import { DownloadStatus } from '@redaction/red-ui-http';
import { IListable } from '@iqser/common-ui';
export class DownloadStatusWrapper implements IListable {
inProgress: boolean;
constructor(private _downloadStatus: DownloadStatus) {}
get id() {
return this.storageId;
}
get searchKey(): string {
return this.storageId;
}
get size() {
const i = this._downloadStatus.fileSize === 0 ? 0 : Math.floor(Math.log(this._downloadStatus.fileSize) / Math.log(1024));
return (this._downloadStatus.fileSize / Math.pow(1024, i)).toFixed(2) + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}
get creationDate() {
return this._downloadStatus.creationDate;
}
get filename() {
return this._downloadStatus.filename;
}
get lastDownload() {
return this._downloadStatus.lastDownload;
}
get mimeType() {
return this._downloadStatus.mimeType;
}
get dossierId() {
return this._downloadStatus.dossierId;
}
get isReady() {
return this._downloadStatus.status === 'READY';
}
get status() {
return this._downloadStatus.status;
}
get storageId() {
return this._downloadStatus.storageId;
}
}

View File

@ -1,59 +1,57 @@
import { ApplicationRef, Injectable } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { DownloadControllerService, FileManagementControllerService } from '@redaction/red-ui-http'; import {
DownloadResponse,
DownloadStatusResponse,
IDownloadStatus,
PrepareDownloadRequest,
RemoveDownloadRequest,
} from '@redaction/red-ui-http';
import { interval, Observable } from 'rxjs'; import { interval, Observable } from 'rxjs';
import { ConfigService } from '@services/config.service'; import { ConfigService } from '@services/config.service';
import { TranslateService } from '@ngx-translate/core'; import { map, mergeMap, tap } from 'rxjs/operators';
import { Dossier } from '@state/model/dossier'; import { DownloadStatus } from '../model/download-status';
import { File } from '@models/file/file';
import { mergeMap, tap } from 'rxjs/operators';
import { DownloadStatusWrapper } from '../model/download-status.wrapper';
import { AppStateService } from '@state/app-state.service';
import { KeycloakService } from 'keycloak-angular'; import { KeycloakService } from 'keycloak-angular';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { List } from '@iqser/common-ui'; import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
@Injectable() @Injectable()
export class FileDownloadService { export class FileDownloadService extends EntitiesService<DownloadStatus, IDownloadStatus> {
downloads: DownloadStatusWrapper[] = []; hasPendingDownloads = false;
hasPendingDownloads;
constructor( constructor(
private readonly _userService: UserService, private readonly _userService: UserService,
private readonly _applicationRef: ApplicationRef,
private readonly _keycloakService: KeycloakService, private readonly _keycloakService: KeycloakService,
private readonly _appStateService: AppStateService,
private readonly _translateService: TranslateService,
private readonly _configService: ConfigService, private readonly _configService: ConfigService,
private readonly _downloadControllerService: DownloadControllerService, protected readonly _injector: Injector,
private readonly _fileManagementControllerService: FileManagementControllerService,
) { ) {
super(_injector, DownloadStatus, 'async/download');
interval(5000).subscribe(() => { interval(5000).subscribe(() => {
if (_userService.currentUser.isUser) { if (_userService.currentUser.isUser) {
this.getDownloadStatus().subscribe(() => {}); this.loadAll().subscribe(() => {});
} }
}); });
} }
downloadFiles(files: List<File>, dossier: Dossier): Observable<any> { downloadFiles(fileIds: List, dossierId: string): Observable<any> {
return this._downloadControllerService return this.prepareDownload({
.prepareDownload({ fileIds,
fileIds: files.map(f => f.fileId), dossierId,
dossierId: dossier.id, }).pipe(mergeMap(() => this.loadAll()));
})
.pipe(mergeMap(() => this.getDownloadStatus()));
} }
getDownloadStatus() { loadAll(): Observable<DownloadStatus[]> {
return this._downloadControllerService.getDownloadStatus().pipe( return this.getStatuses().pipe(
tap(statusResponse => { map(entities => entities.map(entity => new DownloadStatus(entity))),
this.downloads = statusResponse.downloadStatus.map(d => new DownloadStatusWrapper(d)); tap(entities => this.setEntities(entities)),
this.hasPendingDownloads = !!this.downloads.find(f => !f.lastDownload && f.isReady); tap(() => (this.hasPendingDownloads = !!this.all.find(f => !f.lastDownload && f.isReady))),
}),
); );
} }
async performDownload(status: DownloadStatusWrapper) { getStatuses(): Observable<IDownloadStatus[]> {
return super._getOne<DownloadStatusResponse>(['status']).pipe(map(res => res.downloadStatus));
}
async performDownload(status: DownloadStatus) {
const token = await this._keycloakService.getToken(); const token = await this._keycloakService.getToken();
const anchor = document.createElement('a'); const anchor = document.createElement('a');
anchor.href = `${this._configService.values.API_URL}/async/download?access_token=${encodeURIComponent( anchor.href = `${this._configService.values.API_URL}/async/download?access_token=${encodeURIComponent(
@ -66,4 +64,14 @@ export class FileDownloadService {
anchor.click(); anchor.click();
document.body.removeChild(anchor); document.body.removeChild(anchor);
} }
@Validate()
prepareDownload(@RequiredParam() body: PrepareDownloadRequest): Observable<DownloadResponse> {
return this._post(body, `${this._defaultModelPath}/prepare`);
}
@Validate()
delete(@RequiredParam() body: RemoveDownloadRequest): Observable<unknown> {
return super._post(body, `${this._defaultModelPath}/delete`);
}
} }

View File

@ -1,15 +1,15 @@
import { Injectable } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { UserPreferenceControllerService } from '@redaction/red-ui-http'; import { List } from '@redaction/red-ui-http';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
interface UserAttributes { type UserAttributes = Record<string, List>;
[p: string]: string[];
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class UserPreferenceService { export class UserPreferenceService extends GenericService<UserAttributes> {
constructor(private readonly _userPreferenceControllerService: UserPreferenceControllerService) { constructor(protected readonly _injector: Injector) {
super(_injector, 'attributes');
this.reload(); this.reload();
} }
@ -35,7 +35,7 @@ export class UserPreferenceService {
async saveLastOpenedFileForDossier(dossierId: string, fileId: string): Promise<void> { async saveLastOpenedFileForDossier(dossierId: string, fileId: string): Promise<void> {
const key = `Dossier-Recent-${dossierId}`; const key = `Dossier-Recent-${dossierId}`;
this.userAttributes[key] = [fileId]; this.userAttributes[key] = [fileId];
await this._userPreferenceControllerService.savePreferences([fileId], key).toPromise(); await this.savePreferences([fileId], key).toPromise();
} }
toggleDevFeatures(): void { toggleDevFeatures(): void {
@ -44,11 +44,15 @@ export class UserPreferenceService {
} }
reload(): void { reload(): void {
this._userPreferenceControllerService this.getAll<UserAttributes>()
.getAllUserAttributes()
.toPromise() .toPromise()
.then(attributes => { .then(attributes => {
this._userAttributes = attributes ?? {}; this._userAttributes = attributes ?? {};
}); });
} }
@Validate()
savePreferences(@RequiredParam() body: List, @RequiredParam() key: string) {
return this._put(body, `${this._defaultModelPath}/${key}`);
}
} }

View File

@ -1,11 +1,13 @@
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable, Injector } from '@angular/core';
import { KeycloakService } from 'keycloak-angular'; import { KeycloakService } from 'keycloak-angular';
import jwt_decode from 'jwt-decode'; import jwt_decode from 'jwt-decode';
import { IUser, UserControllerService } from '@redaction/red-ui-http'; import { CreateUserRequest, IUser, ResetPasswordRequest, UpdateMyProfileRequest, UpdateProfileRequest } from '@redaction/red-ui-http';
import { wipeCaches } from '@redaction/red-cache'; import { wipeCaches } from '@redaction/red-cache';
import { BASE_HREF } from '../tokens'; import { BASE_HREF } from '../tokens';
import { Subject } from 'rxjs'; import { Observable } from 'rxjs';
import { User } from '@models/user'; import { User } from '@models/user';
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
export interface ProfileModel { export interface ProfileModel {
username?: string; username?: string;
@ -18,16 +20,14 @@ export interface ProfileModel {
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class UserService { export class UserService extends EntitiesService<User, IUser> {
usersReloaded$ = new Subject();
private _allUsers: User[];
private _allRedUsers: User[];
constructor( constructor(
protected readonly _injector: Injector,
@Inject(BASE_HREF) private readonly _baseHref: string, @Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _keycloakService: KeycloakService, private readonly _keycloakService: KeycloakService,
private readonly _userControllerService: UserControllerService, ) {
) {} super(_injector, User, 'user');
}
private _currentUser: User; private _currentUser: User;
@ -36,11 +36,11 @@ export class UserService {
} }
get managerUsers(): User[] { get managerUsers(): User[] {
return this._allRedUsers.filter(user => user.isManager); return this.all.filter(user => user.isManager);
} }
get eligibleUsers(): User[] { get eligibleUsers(): User[] {
return this._allRedUsers.filter(user => user.isUser || user.isManager); return this.all.filter(user => user.isUser || user.isManager);
} }
logout() { logout() {
@ -48,23 +48,13 @@ export class UserService {
this._keycloakService.logout(window.location.origin + this._baseHref).then(); this._keycloakService.logout(window.location.origin + this._baseHref).then();
} }
async loadUsersIfNecessary() { loadAll() {
if (!this._allRedUsers) { const all$ = this._currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true);
await this.loadAllUsers();
}
}
async loadAllUsers() { return all$.pipe(
let allUsers: IUser[]; mapEach(user => new User(user, user.roles, user.userId)),
if (this._currentUser.isUserAdmin) { tap(users => this.setEntities(users)),
allUsers = await this._userControllerService.getAllUsers().toPromise(); );
} else {
allUsers = await this._userControllerService.getUsers().toPromise();
}
this._allUsers = allUsers.map(user => new User(user, user.roles, user.userId));
this._allRedUsers = this._allUsers.filter(user => user.hasAnyREDRoles);
this.usersReloaded$.next();
return this._allUsers;
} }
async loadCurrentUser() { async loadCurrentUser() {
@ -74,16 +64,8 @@ export class UserService {
this._currentUser = new User(await this._keycloakService.loadUserProfile(true), this._keycloakService.getUserRoles(true), userId); this._currentUser = new User(await this._keycloakService.loadUserProfile(true), this._keycloakService.getUserRoles(true), userId);
} }
getRedUserById(id: string) {
return this._allRedUsers.find(u => u.id === id);
}
getUserById(id: string) {
return this._allUsers ? this._allUsers.find(u => u.id === id) : this.getRedUserById(id);
}
getNameForId(userId: string): string | undefined { getNameForId(userId: string): string | undefined {
return this.getUserById(userId)?.name; return this.find(userId)?.name;
} }
hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean { hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean {
@ -99,4 +81,34 @@ export class UserService {
return true; return true;
} }
getUsers(onlyRed = false, refreshCache = false): Observable<IUser[]> {
const url = onlyRed ? `${this._defaultModelPath}/red` : this._defaultModelPath;
return super.getAll(url, [{ key: 'refreshCache', value: refreshCache }]);
}
@Validate()
updateProfile(@RequiredParam() body: UpdateProfileRequest, @RequiredParam() userId: string) {
return this._post<unknown>(body, `${this._defaultModelPath}/profile/${userId}`);
}
@Validate()
updateMyProfile(@RequiredParam() body: UpdateMyProfileRequest) {
return this._post<unknown>(body, `${this._defaultModelPath}/my-profile`);
}
@Validate()
resetPassword(@RequiredParam() body: ResetPasswordRequest, @RequiredParam() userId: string) {
return this._post<unknown>(body, `${this._defaultModelPath}/${userId}/reset-password`);
}
@Validate()
create(@RequiredParam() body: CreateUserRequest) {
return this._post(body);
}
delete(userIds: List) {
const queryParams = userIds.map<QueryParam>(userId => ({ key: 'userId', value: userId }));
return super.delete(userIds, this._defaultModelPath, queryParams);
}
} }

View File

@ -19,11 +19,11 @@ export class AppStateGuard implements CanActivate {
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> { async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
if (this._userService.currentUser.isUserAdmin) { if (this._userService.currentUser.isUserAdmin) {
await this._userService.loadUsersIfNecessary(); await this._userService.loadAllIfEmpty();
} }
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) { if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
await this._userService.loadUsersIfNecessary(); await this._userService.loadAllIfEmpty();
await this._dossierTemplatesService.loadAllIfEmpty(); await this._dossierTemplatesService.loadAllIfEmpty();
await this._appStateService.loadDictionaryDataIfNecessary(); await this._appStateService.loadDictionaryDataIfNecessary();
} }

@ -1 +1 @@
Subproject commit 4e84610f65c8993d9725af62188e3578e9a27e8b Subproject commit c715f73fd3e0b4a70efb60995929877eaa2e8d11

View File

@ -1,12 +1,6 @@
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { Configuration } from './configuration'; import { Configuration } from './configuration';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { AuditControllerService } from './api/auditController.service';
import { DigitalSignatureControllerService } from './api/digitalSignatureController.service';
import { DossierAttributesControllerService } from './api/dossierAttributesController.service';
import { DossierTemplateControllerService } from './api/dossierTemplateController.service';
import { DownloadControllerService } from './api/downloadController.service';
import { FileManagementControllerService } from './api/fileManagementController.service'; import { FileManagementControllerService } from './api/fileManagementController.service';
import { GeneralSettingsControllerService } from './api/generalSettingsController.service'; import { GeneralSettingsControllerService } from './api/generalSettingsController.service';
import { InfoControllerService } from './api/infoController.service'; import { InfoControllerService } from './api/infoController.service';
@ -19,8 +13,6 @@ import { ReportTemplateControllerService } from './api/reportTemplateController.
import { RulesControllerService } from './api/rulesController.service'; import { RulesControllerService } from './api/rulesController.service';
import { SmtpConfigurationControllerService } from './api/smtpConfigurationController.service'; import { SmtpConfigurationControllerService } from './api/smtpConfigurationController.service';
import { UploadControllerService } from './api/uploadController.service'; import { UploadControllerService } from './api/uploadController.service';
import { UserControllerService } from './api/userController.service';
import { UserPreferenceControllerService } from './api/userPreferenceController.service';
import { VersionsControllerService } from './api/versionsController.service'; import { VersionsControllerService } from './api/versionsController.service';
import { ViewedPagesControllerService } from './api/viewedPagesController.service'; import { ViewedPagesControllerService } from './api/viewedPagesController.service';
import { WatermarkControllerService } from './api/watermarkController.service'; import { WatermarkControllerService } from './api/watermarkController.service';
@ -33,11 +25,6 @@ import { StatusReportControllerService } from './api/statusReportController.serv
declarations: [], declarations: [],
exports: [], exports: [],
providers: [ providers: [
AuditControllerService,
DigitalSignatureControllerService,
DossierAttributesControllerService,
DossierTemplateControllerService,
DownloadControllerService,
FileManagementControllerService, FileManagementControllerService,
GeneralSettingsControllerService, GeneralSettingsControllerService,
InfoControllerService, InfoControllerService,
@ -50,8 +37,6 @@ import { StatusReportControllerService } from './api/statusReportController.serv
RulesControllerService, RulesControllerService,
SmtpConfigurationControllerService, SmtpConfigurationControllerService,
UploadControllerService, UploadControllerService,
UserControllerService,
UserPreferenceControllerService,
VersionsControllerService, VersionsControllerService,
ViewedPagesControllerService, ViewedPagesControllerService,
WatermarkControllerService, WatermarkControllerService,
@ -67,7 +52,8 @@ export class ApiModule {
} }
if (!http) { if (!http) {
throw new Error( throw new Error(
'You need to import the HttpClientModule in your AppModule! \n' + 'See also https://github.com/angular/angular/issues/20575', 'You need to import the HttpClientModule in your AppModule! \n' +
'See also https://github.com/angular/angular/issues/20575',
); );
} }
} }

View File

@ -10,7 +10,8 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { IDossierAttributeConfig } from './dossierAttributeConfig'; import { IDossierAttributeConfig } from './dossierAttributeConfig';
import { List } from '../red-types';
export interface DossierAttributesConfig { export interface DossierAttributesConfig {
dossierAttributeConfigs?: Array<IDossierAttributeConfig>; dossierAttributeConfigs: List<IDossierAttributeConfig>;
} }

View File

@ -11,5 +11,5 @@
*/ */
export interface DownloadResponse { export interface DownloadResponse {
storageId?: string; readonly storageId?: string;
} }

View File

@ -9,35 +9,27 @@
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { DownloadFileType } from './dossier';
import { List } from '../red-types';
export interface DownloadStatus { export interface IDownloadStatus {
creationDate?: string; readonly creationDate?: string;
dossierId?: string; readonly dossierId?: string;
downloadFileTypes?: Array<DownloadStatus.DownloadFileTypesEnum>; readonly downloadFileTypes?: List<DownloadFileType>;
fileIds?: Array<string>; readonly fileIds?: List;
fileSize?: number; readonly fileSize?: number;
filename?: string; readonly filename?: string;
lastDownload?: string; readonly lastDownload?: string;
mimeType?: string; readonly mimeType?: string;
status?: DownloadStatus.StatusEnum; readonly status?: DownloadStatusType;
storageId?: string; readonly storageId?: string;
userId?: string; readonly userId?: string;
} }
export namespace DownloadStatus { export const DownloadStatuses = {
export type DownloadFileTypesEnum = 'ANNOTATED' | 'FLATTEN' | 'ORIGINAL' | 'PREVIEW' | 'REDACTED'; FAILED: 'FAILED',
export const DownloadFileTypesEnum = { GENERATING: 'GENERATING',
ANNOTATED: 'ANNOTATED' as DownloadFileTypesEnum, QUEUED: 'QUEUED',
FLATTEN: 'FLATTEN' as DownloadFileTypesEnum, READY: 'READY',
ORIGINAL: 'ORIGINAL' as DownloadFileTypesEnum, } as const;
PREVIEW: 'PREVIEW' as DownloadFileTypesEnum, export type DownloadStatusType = keyof typeof DownloadStatuses;
REDACTED: 'REDACTED' as DownloadFileTypesEnum,
};
export type StatusEnum = 'FAILED' | 'GENERATING' | 'QUEUED' | 'READY';
export const StatusEnum = {
FAILED: 'FAILED' as StatusEnum,
GENERATING: 'GENERATING' as StatusEnum,
QUEUED: 'QUEUED' as StatusEnum,
READY: 'READY' as StatusEnum,
};
}

View File

@ -9,8 +9,8 @@
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { DownloadStatus } from './downloadStatus'; import { IDownloadStatus } from './downloadStatus';
export interface DownloadStatusResponse { export interface DownloadStatusResponse {
downloadStatus?: Array<DownloadStatus>; downloadStatus?: IDownloadStatus[];
} }

View File

@ -10,10 +10,12 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { List } from '../red-types';
/** /**
* Object containing information on which file and report types should be included in the download. * Object containing information on which file and report types should be included in the download.
*/ */
export interface PrepareDownloadRequest { export interface PrepareDownloadRequest {
dossierId?: string; readonly dossierId?: string;
fileIds?: Array<string>; readonly fileIds?: List;
} }