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
trim_trailing_whitespace = false
[*.ts]
ij_typescript_use_double_quotes = false
ij_typescript_enforce_trailing_comma = keep
[{*.json, .prettierrc, .eslintrc}]
indent_size = 2

View File

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

View File

@ -24,8 +24,8 @@
></iqser-circle-button>
</ng-template>
<ng-template #tableItemTemplate let-download="entity">
<div>
<ng-template #tableItemTemplate let-entity="entity">
<div *ngIf="cast(entity) as download">
<div class="cell">
<div [class.no-bold]="download.lastDownload" class="table-item-title heading">
{{ 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 { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper';
import { DownloadControllerService } from '@redaction/red-ui-http';
import { CircleButtonTypes, DefaultListingServices, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui';
import { DownloadStatus } from '@upload-download/model/download-status';
import {
CircleButtonTypes,
DefaultListingServicesTmp,
EntitiesService,
ListingComponent,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { timer } from 'rxjs';
import { RouterHistoryService } from '@services/router-history.service';
@Component({
selector: 'redaction-downloads-list-screen',
templateUrl: './downloads-list-screen.component.html',
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 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.size') },
{ label: _('downloads-list.table-col-names.date') },
@ -28,37 +40,27 @@ export class DownloadsListScreenComponent extends ListingComponent<DownloadStatu
private readonly _loadingService: LoadingService,
readonly fileDownloadService: FileDownloadService,
readonly routerHistoryService: RouterHistoryService,
private readonly _downloadControllerService: DownloadControllerService,
) {
super(_injector);
this._loadingService.loadWhile(this._loadData());
}
async ngOnInit() {
this._loadingService.start();
await this._loadData();
this.addSubscription = timer(0, 5000).subscribe(async () => {
await this._loadData();
});
this._loadingService.stop();
}
downloadItem(download: DownloadStatusWrapper) {
downloadItem(download: DownloadStatus) {
this._loadingService.loadWhile(this.fileDownloadService.performDownload(download));
}
deleteItems(downloads?: DownloadStatusWrapper[]) {
deleteItems(downloads?: DownloadStatus[]) {
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);
await this._downloadControllerService.deleteDownload({ storageIds }).toPromise();
await this.fileDownloadService.delete({ storageIds }).toPromise();
this.listingService.setSelected([]);
await this._loadData();
}
private async _loadData() {
await this.fileDownloadService.getDownloadStatus().toPromise();
this.entitiesService.setEntities(this.fileDownloadService.downloads);
await this.fileDownloadService.loadAll().toPromise();
}
}

View File

@ -4,7 +4,6 @@ import { ProfileModel, UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { LanguageService } from '@i18n/language.service';
import { TranslateService } from '@ngx-translate/core';
import { UserControllerService } from '@redaction/red-ui-http';
import { ConfigService } from '@services/config.service';
import { DomSanitizer } from '@angular/platform-browser';
import { languagesTranslations } from '../../translations/languages-translations';
@ -27,7 +26,6 @@ export class UserProfileScreenComponent implements OnInit {
private readonly _formBuilder: FormBuilder,
private readonly _userService: UserService,
private readonly _configService: ConfigService,
private readonly _userControllerService: UserControllerService,
private readonly _languageService: LanguageService,
private readonly _domSanitizer: DomSanitizer,
private readonly _translateService: TranslateService,
@ -82,14 +80,14 @@ export class UserProfileScreenComponent implements OnInit {
const value = this.formGroup.value as ProfileModel;
delete value.language;
await this._userControllerService
await this._userService
.updateMyProfile({
...value,
})
.toPromise();
await this._userService.loadCurrentUser();
await this._userService.loadAllUsers();
await this._userService.loadAll().toPromise();
}
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 { DossierAttributesListingScreenComponent } from './screens/dossier-attributes-listing/dossier-attributes-listing-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 = [
AddEditDossierTemplateDialogComponent,
@ -88,7 +90,7 @@ const components = [
@NgModule({
declarations: [...components],
providers: [AdminDialogService],
providers: [AdminDialogService, AuditService, DigitalSignatureService],
imports: [CommonModule, SharedModule, AdminRoutingModule, NgxChartsModule, ColorPickerModule, MonacoEditorModule],
})
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 { Router } from '@angular/router';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { UserService } from '@services/user.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -18,7 +17,7 @@ export class DossierTemplateActionsComponent implements OnInit {
readonly currentUser = this._userService.currentUser;
@Input() dossierTemplateId: string;
@Output() loadDossierTemplatesData = new EventEmitter<any>();
@Output() readonly loadDossierTemplatesData = new EventEmitter<void>();
constructor(
private readonly _router: Router,
@ -26,9 +25,8 @@ export class DossierTemplateActionsComponent implements OnInit {
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dialogService: AdminDialogService,
private readonly _dossierTemplateControllerService: DossierTemplateControllerService,
private readonly _dossierTemplatesService: DossierTemplatesService,
) {}
get dossierTemplate() {
@ -41,7 +39,7 @@ export class DossierTemplateActionsComponent implements OnInit {
openEditDossierTemplateDialog($event: any) {
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._loadingService.start();
await this._dossierTemplateControllerService
.deleteDossierTemplates([this.dossierTemplateId])
await this._dossierTemplatesService
.delete([this.dossierTemplateId])
.toPromise()
.catch(error => {
if (error.status === 409) {
@ -60,12 +58,11 @@ export class DossierTemplateActionsComponent implements OnInit {
}
this._loadingService.stop();
});
await this._dossierTemplateControllerService.deleteDossierTemplates([this.dossierTemplateId]).toPromise();
await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData();
await this._router.navigate(['main', 'admin']);
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._dossierAttributesService.addOrUpdateConfig(attribute).subscribe(
this._dossierAttributesService.createOrUpdate(attribute).subscribe(
() => {
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 * as 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 { downloadTypesTranslations } from '../../../../translations/download-types-translations';
import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service';
@Component({
selector: 'redaction-add-edit-dossier-template-dialog',
templateUrl: './add-edit-dossier-template-dialog.component.html',
styleUrls: ['./add-edit-dossier-template-dialog.component.scss'],
})
@ -31,7 +30,6 @@ export class AddEditDossierTemplateDialogComponent {
private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _formBuilder: FormBuilder,
private readonly _dossierTemplateController: DossierTemplateControllerService,
public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly dossierTemplate: IDossierTemplate,
) {
@ -99,7 +97,7 @@ export class AddEditDossierTemplateDialogComponent {
validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').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._appStateService.loadDictionaryData();
this.dialogRef.close(true);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import { Component, forwardRef, Injector, OnDestroy, OnInit } from '@angular/core';
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 { applyIntervalConstraints } from '@utils/date-inputs-utils';
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 { UserService } from '@services/user.service';
import { Audit } from '@models/audit.model';
import { AuditService } from '../../services/audit.service';
const PAGE_SIZE = 50;
@ -41,7 +42,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnD
protected readonly _injector: Injector,
private readonly _formBuilder: FormBuilder,
private readonly _loadingService: LoadingService,
private readonly _auditControllerService: AuditControllerService,
private readonly _auditService: AuditService,
) {
super(_injector);
this.filterForm = this._formBuilder.group({
@ -102,8 +103,8 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnD
to,
};
promises.push(this._auditControllerService.getAuditCategories().toPromise());
promises.push(this._auditControllerService.searchAuditLog(logsRequestBody).toPromise());
promises.push(this._auditService.getCategories().toPromise());
promises.push(this._auditService.searchAuditLog(logsRequestBody).toPromise());
const data = await Promise.all(promises);
this.categories = data[0].map(c => c.category);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,7 +13,6 @@ import {
TableColumnConfig,
Toaster,
} from '@iqser/common-ui';
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
import { UserService } from '@services/user.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RouterHistoryService } from '@services/router-history.service';
@ -42,22 +41,21 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
];
constructor(
protected readonly _injector: Injector,
private readonly _toaster: Toaster,
protected readonly _injector: Injector,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _appStateService: AppStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dialogService: AdminDialogService,
readonly routerHistoryService: RouterHistoryService,
readonly userPreferenceService: UserPreferenceService,
private readonly _dossierTemplateControllerService: DossierTemplateControllerService,
private readonly _dossierTemplatesService: DossierTemplatesService,
) {
super(_injector);
}
ngOnInit(): void {
this.loadDossierTemplatesData();
this.loadDossierTemplateStats();
}
openBulkDeleteTemplatesDialog($event?: MouseEvent) {
@ -66,35 +64,13 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
});
}
loadDossierTemplatesData() {
this._appStateService.reset();
this._loadDossierTemplateStats();
}
openAddDossierTemplateDialog() {
this._dialogService.openDialog('addEditDossierTemplate', null, null, () => {
this.loadDossierTemplatesData();
this.loadDossierTemplateStats();
});
}
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) {
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() {
loadDossierTemplateStats() {
this.entitiesService.all.forEach(rs => {
const dictionaries = this._appStateService.dictionaryData[rs.dossierTemplateId];
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>
</ng-template>
<ng-template #tableItemTemplate let-attribute="entity">
<div>
<ng-template #tableItemTemplate let-entity="entity">
<div *ngIf="cast(entity) as attribute">
<div class="label cell">
<span>{{ attribute.label }}</span>
</div>

View File

@ -41,7 +41,7 @@
</ng-template>
<ng-template #tableItemTemplate let-entity="entity">
<div>
<div *ngIf="cast(entity) as entity">
<div class="cell filename">
<div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above">
{{ entity.dossierName }}
@ -63,7 +63,7 @@
</div>
<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 class="cell">

View File

@ -65,10 +65,10 @@
></iqser-circle-button>
</ng-template>
<ng-template #tableItemTemplate let-user="entity">
<div>
<ng-template #tableItemTemplate let-entity="entity">
<div *ngIf="cast(entity) as user">
<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 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 { UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { TranslateService } from '@ngx-translate/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service';
import {
CircleButtonTypes,
DefaultListingServices,
DefaultListingServicesTmp,
EntitiesService,
IconButtonTypes,
ListingComponent,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { rolesTranslations } from '../../../../translations/roles-translations';
@ -23,7 +22,14 @@ import { User } from '@models/user';
@Component({
templateUrl: './user-listing-screen.component.html',
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 {
readonly translations = rolesTranslations;
@ -40,8 +46,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
];
collapsedDetails = false;
chartData: DoughnutChartConfig[] = [];
@ViewChildren(InitialsAvatarComponent)
private readonly _avatars: QueryList<InitialsAvatarComponent>;
constructor(
readonly userService: UserService,
@ -49,7 +53,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
private readonly _loadingService: LoadingService,
private readonly _dialogService: AdminDialogService,
private readonly _translateService: TranslateService,
private readonly _userControllerService: UserControllerService,
private readonly _translateChartService: TranslateChartService,
) {
super(_injector);
@ -87,9 +90,8 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
async toggleActive(user: User) {
this._loadingService.start();
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();
this._avatars.find(item => item.userId === user.id).detectChanges();
}
bulkDelete() {
@ -97,7 +99,7 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
}
private async _loadData() {
this.entitiesService.setEntities(await this.userService.loadAllUsers());
await this.userService.loadAll().toPromise();
this._computeStats();
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>
<iqser-input-with-action
[(value)]="searchQuery"
(valueChange)="setMembersSelectOptions()"
[(value)]="searchQuery"
[placeholder]="'assign-dossier-owner.dialog.search' | translate"
[width]="560"
class="search-container"
@ -49,7 +49,7 @@
*ngFor="let userId of membersSelectOptions"
[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 (click)="toggleApprover(userId, $event)" *ngIf="!isOwner(userId)" class="make-approver">
<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,
value: this.currentAttrValue(attr),
}));
await this._dossierAttributesService.setValues(this.dossier, dossierAttributeList);
await this._dossierAttributesService.setAttributes(this.dossier, dossierAttributeList).toPromise();
await this._loadAttributes();
this.updateDossier.emit();
this._loadingService.stop();
@ -134,7 +134,7 @@ export class EditDossierAttributesComponent implements EditDossierSectionInterfa
}
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.imageAttributes = this.attributes.filter(attr => this.isImage(attr));
}

View File

@ -34,8 +34,8 @@
></iqser-circle-button>
</ng-template>
<ng-template #tableItemTemplate let-file="entity">
<div>
<ng-template #tableItemTemplate let-entity="entity">
<div *ngIf="cast(entity) as file">
<div class="cell filename">
<span>{{ file.filename }}</span>
</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 { 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 { UserPreferenceControllerService } from '@redaction/red-ui-http';
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 { TeamMembersManagerComponent } from './components/team-members-manager/team-members-manager.component';
@ -85,7 +84,6 @@ const services = [
PdfViewerDataService,
AnnotationDrawService,
AnnotationProcessingService,
UserPreferenceControllerService,
];
@NgModule({

View File

@ -15,7 +15,7 @@
<div class="all-caps-label" translate="dossier-details.owner"></div>
<div class="mt-12 d-flex">
<ng-container *ngIf="!editingOwner; else editOwner">
<redaction-initials-avatar [userId]="owner?.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
(action)="editingOwner = true"

View File

@ -46,7 +46,7 @@ export class DossierDetailsComponent implements OnInit {
}
ngOnInit(): void {
this.owner = this._userService.getRedUserById(this.dossiersService.activeDossier.ownerId);
this.owner = this._userService.find(this.dossiersService.activeDossier.ownerId);
this.calculateChartConfig();
this.appStateService.fileChanged$.subscribe(() => {
this.calculateChartConfig();
@ -75,7 +75,7 @@ export class DossierDetailsComponent implements OnInit {
}
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 dossierRequest: DossierRequest = { ...activeDossier, dossierId: activeDossier.dossierId, ownerId: this.owner.id };
await this.dossiersService.createOrUpdate(dossierRequest).toPromise();

View File

@ -34,7 +34,7 @@
</div>
<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 *ngIf="!file.isError" class="cell">

View File

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

View File

@ -5,7 +5,7 @@
<redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge>
</div>
<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 class="cell status-container">
<redaction-dossiers-listing-actions (actionPerformed)="calculateData.emit()" [dossier]="dossier"></redaction-dossiers-listing-actions>

View File

@ -42,7 +42,7 @@
<redaction-initials-avatar
*ngIf="!editingReviewer"
[userId]="currentReviewer"
[user]="currentReviewer"
[withName]="!!currentReviewer"
tooltipPosition="below"
></redaction-initials-avatar>
@ -83,7 +83,7 @@
<ng-container *ngIf="permissionsService.isApprover() && !!lastReviewer">
<div class="vertical-line"></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>
<div class="vertical-line"></div>

View File

@ -28,7 +28,7 @@ import { PermissionsService } from '@services/permissions.service';
import { timer } from 'rxjs';
import { UserPreferenceService } from '@services/user-preference.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 { download } from '@utils/file-download-utils';
import { ViewMode } from '@models/file/view-mode';
@ -88,7 +88,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
readonly permissionsService: PermissionsService,
readonly userPreferenceService: UserPreferenceService,
readonly userService: UserService,
private readonly _userPreferenceControllerService: UserPreferenceControllerService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _activatedRoute: ActivatedRoute,
private readonly _dialogService: DossiersDialogService,

View File

@ -21,8 +21,8 @@
</div>
</section>
<ng-template #tableItemTemplate let-item="entity">
<div>
<ng-template #tableItemTemplate let-entity="entity">
<div *ngIf="cast(entity) as item">
<div class="cell filename">
<div [matTooltip]="item.filename" class="table-item-title heading" matTooltipPosition="above">
<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 { IDossierTemplate } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core';
@ -59,4 +59,13 @@ export class DossierTemplatesService extends EntitiesService<DossierTemplate, ID
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>
<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>

View File

@ -45,7 +45,10 @@ export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestr
downloadFiles($event: MouseEvent) {
$event.stopPropagation();
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')));
}
}

View File

@ -1,5 +1,5 @@
<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>
</button>
<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
[className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')"
[matTooltipPosition]="tooltipPosition"
[matTooltip]="displayName || ('initials-avatar.unassigned' | translate)"
[matTooltip]="userName"
>
{{ initials }}
{{ _user | name: { showInitials: true, defaultValue: ('initials-avatar.unassigned' | translate) } }}
</div>
<div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username">
{{ displayName || ('initials-avatar.unassigned' | translate) }}
{{ userName }}
</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 { TranslateService } from '@ngx-translate/core';
import { AutoUnsubscribe } from '@iqser/common-ui';
import { User } from '@models/user';
import { TranslateService } from '@ngx-translate/core';
import { NamePipeOptions } from '@shared/pipes/name.pipe';
@Component({
selector: 'redaction-initials-avatar',
@ -11,39 +12,47 @@ import { User } from '@models/user';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy {
@Input() userId: string;
@Input() color = 'lightgray';
@Input() size: 'small' | 'large' = 'small';
@Input() withName = false;
@Input() showYou = false;
@Input() tooltipPosition: 'below' | 'above' = 'above';
displayName: string;
initials: string;
colorClass: string;
user: User;
constructor(
private readonly _userService: UserService,
private readonly _translateService: TranslateService,
private readonly _changeDetectorRef: ChangeDetectorRef,
) {
readonly namePipeOptions: NamePipeOptions = {
showYou: this.showYou,
defaultValue: this._translateService.instant('initials-avatar.unassigned'),
};
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {
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 {
return !!this.user && !this._isCurrentUser && this.user.isManager;
return !!this._user && !this.isCurrentUser && this._user.isManager;
}
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() {
if (this._isCurrentUser) {
if (this.isCurrentUser) {
return 'primary-white';
}
if (this.disabled) {
@ -56,44 +65,13 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange
return `${this.color}-dark`;
}
private get _isCurrentUser(): boolean {
return this._userService.currentUser.id === this.user?.id;
}
ngOnChanges(): void {
const isSystemUser = this.userId?.toLowerCase() === 'system';
const isSystemUser = this._user?.id?.toLowerCase() === 'system';
if (isSystemUser) {
this.displayName = 'System';
this.initials = 'SY';
this.colorClass = 'primary-white primary';
return;
}
this.user = this._userService.getUserById(this.userId);
this.displayName = this._userService.getNameForId(this.userId);
this.initials = this._getInitials();
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="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">
<mat-icon svgIcon="iqser:close"></mat-icon>
</div>

View File

@ -3,16 +3,61 @@ import { UserService } from '@services/user.service';
import { TranslateService } from '@ngx-translate/core';
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({
name: 'name',
})
export class NamePipe implements PipeTransform {
private readonly _defaultOptions: NamePipeOptions = { defaultValue: this._translateService.instant('unknown') };
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {}
transform(value: User | string): string {
if (typeof value === 'string') {
return this._userService.getNameForId(value) || this._translateService.instant('unknown');
transform(value?: User | string, options = this._defaultOptions): string {
let name;
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 { DossierAttribute, DossierAttributes, DossierAttributesControllerService, IDossierAttributeConfig } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core';
import { DossierAttribute, DossierAttributes, DossierAttributesConfig, IDossierAttributeConfig } from '@redaction/red-ui-http';
import { Dossier } from '@state/model/dossier';
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
import { Observable } from 'rxjs';
import { DossierAttributeConfig } from '@state/model/dossier-attribute-config';
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({
providedIn: 'root',
})
export class DossierAttributesService {
constructor(
private readonly _dossierAttributesControllerService: DossierAttributesControllerService,
private readonly _dossierTemplatesService: DossierTemplatesService,
) {}
export class DossierAttributesService extends EntitiesService<DossierAttributeConfig, IDossierAttributeConfig> {
constructor(private readonly _dossierTemplatesService: DossierTemplatesService, protected readonly _injector: Injector) {
super(_injector, DossierAttributeConfig, 'dossier-attributes');
}
async getValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> {
const attributes = await this._dossierAttributesControllerService.getDossierAttributes(dossier.id).toPromise();
const attributesConfig = await this._dossierAttributesControllerService
.getDossierAttributesConfig(dossier.dossierTemplateId)
.toPromise();
async getWithValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> {
const attributes = await this.getAttributes(dossier.id).toPromise();
const attributesConfig = await this.getConfig(dossier.dossierTemplateId).toPromise();
return attributesConfig.dossierAttributeConfigs.map(config => ({
return attributesConfig.map(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> {
return this._dossierAttributesControllerService.setDossierAttributes({ dossierAttributeList }, dossier.id).toPromise();
@Validate()
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> {
return this._dossierAttributesControllerService.deleteDossierAttributesConfig(ids, dossierTemplateId).toPromise();
@Validate()
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[]> {
const config$ = this._dossierAttributesControllerService.getDossierAttributesConfig(dossierTemplateId);
const result = (await config$.toPromise())?.dossierAttributeConfigs || [];
return result.map(item => new DossierAttributeConfig(item));
loadAll(dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Observable<DossierAttributeConfig[]> {
return this.getConfig(dossierTemplateId).pipe(
map(entities => entities ?? []),
mapEach(entity => new DossierAttributeConfig(entity)),
tap(entities => this.setEntities(entities)),
);
}
addOrUpdateConfig(
attribute: IDossierAttributeConfig,
@Validate()
createOrUpdate(
@RequiredParam() attributeConfig: IDossierAttributeConfig,
dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId,
): 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 { DownloadControllerService, FileManagementControllerService } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core';
import {
DownloadResponse,
DownloadStatusResponse,
IDownloadStatus,
PrepareDownloadRequest,
RemoveDownloadRequest,
} from '@redaction/red-ui-http';
import { interval, Observable } from 'rxjs';
import { ConfigService } from '@services/config.service';
import { TranslateService } from '@ngx-translate/core';
import { Dossier } from '@state/model/dossier';
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 { map, mergeMap, tap } from 'rxjs/operators';
import { DownloadStatus } from '../model/download-status';
import { KeycloakService } from 'keycloak-angular';
import { UserService } from '@services/user.service';
import { List } from '@iqser/common-ui';
import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
@Injectable()
export class FileDownloadService {
downloads: DownloadStatusWrapper[] = [];
hasPendingDownloads;
export class FileDownloadService extends EntitiesService<DownloadStatus, IDownloadStatus> {
hasPendingDownloads = false;
constructor(
private readonly _userService: UserService,
private readonly _applicationRef: ApplicationRef,
private readonly _keycloakService: KeycloakService,
private readonly _appStateService: AppStateService,
private readonly _translateService: TranslateService,
private readonly _configService: ConfigService,
private readonly _downloadControllerService: DownloadControllerService,
private readonly _fileManagementControllerService: FileManagementControllerService,
protected readonly _injector: Injector,
) {
super(_injector, DownloadStatus, 'async/download');
interval(5000).subscribe(() => {
if (_userService.currentUser.isUser) {
this.getDownloadStatus().subscribe(() => {});
this.loadAll().subscribe(() => {});
}
});
}
downloadFiles(files: List<File>, dossier: Dossier): Observable<any> {
return this._downloadControllerService
.prepareDownload({
fileIds: files.map(f => f.fileId),
dossierId: dossier.id,
})
.pipe(mergeMap(() => this.getDownloadStatus()));
downloadFiles(fileIds: List, dossierId: string): Observable<any> {
return this.prepareDownload({
fileIds,
dossierId,
}).pipe(mergeMap(() => this.loadAll()));
}
getDownloadStatus() {
return this._downloadControllerService.getDownloadStatus().pipe(
tap(statusResponse => {
this.downloads = statusResponse.downloadStatus.map(d => new DownloadStatusWrapper(d));
this.hasPendingDownloads = !!this.downloads.find(f => !f.lastDownload && f.isReady);
}),
loadAll(): Observable<DownloadStatus[]> {
return this.getStatuses().pipe(
map(entities => entities.map(entity => new DownloadStatus(entity))),
tap(entities => this.setEntities(entities)),
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 anchor = document.createElement('a');
anchor.href = `${this._configService.values.API_URL}/async/download?access_token=${encodeURIComponent(
@ -66,4 +64,14 @@ export class FileDownloadService {
anchor.click();
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 { UserPreferenceControllerService } from '@redaction/red-ui-http';
import { Injectable, Injector } from '@angular/core';
import { List } from '@redaction/red-ui-http';
import { GenericService, RequiredParam, Validate } from '@iqser/common-ui';
interface UserAttributes {
[p: string]: string[];
}
type UserAttributes = Record<string, List>;
@Injectable({
providedIn: 'root',
})
export class UserPreferenceService {
constructor(private readonly _userPreferenceControllerService: UserPreferenceControllerService) {
export class UserPreferenceService extends GenericService<UserAttributes> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'attributes');
this.reload();
}
@ -35,7 +35,7 @@ export class UserPreferenceService {
async saveLastOpenedFileForDossier(dossierId: string, fileId: string): Promise<void> {
const key = `Dossier-Recent-${dossierId}`;
this.userAttributes[key] = [fileId];
await this._userPreferenceControllerService.savePreferences([fileId], key).toPromise();
await this.savePreferences([fileId], key).toPromise();
}
toggleDevFeatures(): void {
@ -44,11 +44,15 @@ export class UserPreferenceService {
}
reload(): void {
this._userPreferenceControllerService
.getAllUserAttributes()
this.getAll<UserAttributes>()
.toPromise()
.then(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 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 { BASE_HREF } from '../tokens';
import { Subject } from 'rxjs';
import { Observable } from 'rxjs';
import { User } from '@models/user';
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
export interface ProfileModel {
username?: string;
@ -18,16 +20,14 @@ export interface ProfileModel {
@Injectable({
providedIn: 'root',
})
export class UserService {
usersReloaded$ = new Subject();
private _allUsers: User[];
private _allRedUsers: User[];
export class UserService extends EntitiesService<User, IUser> {
constructor(
protected readonly _injector: Injector,
@Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _keycloakService: KeycloakService,
private readonly _userControllerService: UserControllerService,
) {}
) {
super(_injector, User, 'user');
}
private _currentUser: User;
@ -36,11 +36,11 @@ export class UserService {
}
get managerUsers(): User[] {
return this._allRedUsers.filter(user => user.isManager);
return this.all.filter(user => user.isManager);
}
get eligibleUsers(): User[] {
return this._allRedUsers.filter(user => user.isUser || user.isManager);
return this.all.filter(user => user.isUser || user.isManager);
}
logout() {
@ -48,23 +48,13 @@ export class UserService {
this._keycloakService.logout(window.location.origin + this._baseHref).then();
}
async loadUsersIfNecessary() {
if (!this._allRedUsers) {
await this.loadAllUsers();
}
}
loadAll() {
const all$ = this._currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true);
async loadAllUsers() {
let allUsers: IUser[];
if (this._currentUser.isUserAdmin) {
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;
return all$.pipe(
mapEach(user => new User(user, user.roles, user.userId)),
tap(users => this.setEntities(users)),
);
}
async loadCurrentUser() {
@ -74,16 +64,8 @@ export class UserService {
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 {
return this.getUserById(userId)?.name;
return this.find(userId)?.name;
}
hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean {
@ -99,4 +81,34 @@ export class UserService {
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> {
if (this._userService.currentUser.isUserAdmin) {
await this._userService.loadUsersIfNecessary();
await this._userService.loadAllIfEmpty();
}
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
await this._userService.loadUsersIfNecessary();
await this._userService.loadAllIfEmpty();
await this._dossierTemplatesService.loadAllIfEmpty();
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 { Configuration } from './configuration';
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 { GeneralSettingsControllerService } from './api/generalSettingsController.service';
import { InfoControllerService } from './api/infoController.service';
@ -19,8 +13,6 @@ import { ReportTemplateControllerService } from './api/reportTemplateController.
import { RulesControllerService } from './api/rulesController.service';
import { SmtpConfigurationControllerService } from './api/smtpConfigurationController.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 { ViewedPagesControllerService } from './api/viewedPagesController.service';
import { WatermarkControllerService } from './api/watermarkController.service';
@ -33,11 +25,6 @@ import { StatusReportControllerService } from './api/statusReportController.serv
declarations: [],
exports: [],
providers: [
AuditControllerService,
DigitalSignatureControllerService,
DossierAttributesControllerService,
DossierTemplateControllerService,
DownloadControllerService,
FileManagementControllerService,
GeneralSettingsControllerService,
InfoControllerService,
@ -50,8 +37,6 @@ import { StatusReportControllerService } from './api/statusReportController.serv
RulesControllerService,
SmtpConfigurationControllerService,
UploadControllerService,
UserControllerService,
UserPreferenceControllerService,
VersionsControllerService,
ViewedPagesControllerService,
WatermarkControllerService,
@ -67,7 +52,8 @@ export class ApiModule {
}
if (!http) {
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.
*/
import { IDossierAttributeConfig } from './dossierAttributeConfig';
import { List } from '../red-types';
export interface DossierAttributesConfig {
dossierAttributeConfigs?: Array<IDossierAttributeConfig>;
dossierAttributeConfigs: List<IDossierAttributeConfig>;
}

View File

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

View File

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

View File

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

View File

@ -10,10 +10,12 @@
* 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.
*/
export interface PrepareDownloadRequest {
dossierId?: string;
fileIds?: Array<string>;
readonly dossierId?: string;
readonly fileIds?: List;
}