From bfd45a88944be8816136eb0529707e54831c34a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 9 Aug 2021 16:06:26 +0300 Subject: [PATCH 1/4] Trash screen & some other improvements --- .../downloads-list-screen.component.ts | 17 ++- .../screens/trash/trash-screen.component.html | 85 ++++------- .../screens/trash/trash-screen.component.scss | 9 +- .../screens/trash/trash-screen.component.ts | 136 ++++++++++++------ .../dossier-listing-screen.component.ts | 2 +- .../table-header/table-header.component.html | 7 +- apps/red-ui/src/assets/config/config.json | 4 +- .../red-ui/src/assets/icons/general/enter.svg | 7 +- .../src/assets/icons/general/put-back.svg | 1 - 9 files changed, 150 insertions(+), 118 deletions(-) diff --git a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts index cd2ea8848..aaf77cc26 100644 --- a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts +++ b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts @@ -5,6 +5,7 @@ import { DownloadControllerService } from '@redaction/red-ui-http'; import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component'; import { CircleButtonTypes, TableColumnConfig } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { LoadingService } from '@services/loading.service'; @Component({ selector: 'redaction-downloads-list-screen', @@ -27,22 +28,28 @@ export class DownloadsListScreenComponent extends BaseListingComponent d.storageId); + deleteItems(downloads?: DownloadStatusWrapper[]) { + this._loadingService.loadWhile(this._deleteItems(downloads)); + } + + private async _deleteItems(downloads?: DownloadStatusWrapper[]) { + const storageIds = (downloads || this.screenStateService.selectedEntities).map(d => d.storageId); await this._downloadControllerService.deleteDownload({ storageIds }).toPromise(); + this.screenStateService.setSelectedEntities([]); await this._loadData(); } diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html index ae24d7d02..49d2932ba 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html @@ -5,55 +5,12 @@
-
- - - - {{ 'trash.table-header.title' | translate: { length: (entitiesService.displayedLength$ | async) } }} - - - - - -
- -
-
- - - - - -
-
+
@@ -125,3 +82,23 @@
+ + +
+ + + +
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss index 41c1395e0..9bebde5ca 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss @@ -1,11 +1,12 @@ @import '../../../../../assets/styles/variables'; @import '../../../../../assets/styles/red-mixins'; -.header-item { - padding: 0 24px 0 10px; +.bulk-actions { + display: flex; + align-items: center; - iqser-circle-button:not(:last-child) { - margin-right: 4px !important; + > *:not(:last-child) { + margin-right: 2px; } } diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts index e26cf9d5d..64c049be6 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts @@ -10,20 +10,49 @@ import { DossiersService } from '../../../dossier/services/dossiers.service'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { ConfirmationDialogInput, TitleColors } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { Observable } from 'rxjs'; +import { distinctUntilChanged, map } from 'rxjs/operators'; const HOURS_IN_A_DAY = 24; const MINUTES_IN_AN_HOUR = 60; +interface DossierListItem extends Dossier { + readonly canRestore: boolean; +} + @Component({ templateUrl: './trash-screen.component.html', styleUrls: ['./trash-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, providers: [...DefaultListingServices, DossiersService] }) -export class TrashScreenComponent extends BaseListingComponent implements OnInit { - readonly itemSize = 80; - protected readonly _primaryKey = 'dossierName'; +export class TrashScreenComponent extends BaseListingComponent implements OnInit { readonly circleButtonTypes = CircleButtonTypes; + readonly itemSize = 80; + readonly tableColConfigs: TableColConfig[] = [ + { + label: _('trash.table-col-names.name'), + withSort: true, + column: 'dossierName' + }, + { + label: _('trash.table-col-names.owner'), + class: 'user-column' + }, + { + label: _('trash.table-col-names.deleted-on'), + withSort: true, + column: 'softDeletedTime' + }, + { + label: _('trash.table-col-names.time-to-restore'), + withSort: true, + column: 'softDeletedTime' + } + ]; + readonly canRestoreSelected$ = this._canRestoreSelected$; + protected readonly _primaryKey = 'dossierName'; + protected readonly _tableHeaderLabel = 'trash.table-header.title'; private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS); constructor( @@ -37,51 +66,22 @@ export class TrashScreenComponent extends BaseListingComponent implemen super(_injector); } + private get _canRestoreSelected$(): Observable { + return this.screenStateService.selectedEntities$.pipe( + map(entities => entities.length && this._canRestore()), + distinctUntilChanged() + ); + } + async ngOnInit(): Promise { - this._loadingService.start(); - - await this.loadDossierTemplatesData(); - - this._loadingService.stop(); - } - - async loadDossierTemplatesData(): Promise { - this.entitiesService.setEntities(await this._dossiersService.getDeleted()); - } - - canRestore(softDeletedTime: string): boolean { - const date = moment(this.getRestoreDate(softDeletedTime)); - const now = new Date(Date.now()); - - const daysLeft = date.diff(now, 'days'); - const hoursFromNow = date.diff(now, 'hours'); - const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft; - const minutesFromNow = date.diff(now, 'minutes'); - const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft; - - return daysLeft >= 0 && hoursLeft >= 0 && minutesLeft > 0; + this._loadingService.loadWhile(this._loadDossiersData()); } getRestoreDate(softDeletedTime: string): string { return moment(softDeletedTime).add(this._deleteRetentionHours, 'hours').toISOString(); } - bulkDelete(dossiers = this.entitiesService.selected) { - this._loadingService.loadWhile(this._hardDelete(dossiers)); - } - - bulkRestore(dossierIds = this.entitiesService.selected.map(d => d.dossierId)) { - this._loadingService.loadWhile(this._restore(dossierIds)); - } - - private async _restore(dossierIds: string[]): Promise { - this._loadingService.start(); - await this._dossiersService.restore(dossierIds); - this._removeFromList(dossierIds); - this._loadingService.stop(); - } - - private async _hardDelete(dossiers: Dossier[]): Promise { + hardDelete(dossiers = this.screenStateService.selectedEntities) { const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS'); const data = new ConfirmationDialogInput({ title: dossiers.length > 1 ? _('confirmation-dialog.delete-dossier.title-alt') : _('confirmation-dialog.delete-dossier.title'), @@ -94,14 +94,58 @@ export class TrashScreenComponent extends BaseListingComponent implemen translateParams: { dossierName: dossiers[0].dossierName, period: period } }); this._adminDialogService.openDialog('confirm', null, data, async () => { - this._loadingService.start(); - const dossierIds = dossiers.map(d => d.dossierId); - await this._dossiersService.hardDelete(dossierIds); - this._removeFromList(dossierIds); - this._loadingService.stop(); + this._loadingService.loadWhile(this._hardDelete(dossiers)); }); } + restore(dossiers = this.screenStateService.selectedEntities) { + this._loadingService.loadWhile(this._restore(dossiers)); + } + + private async _loadDossiersData(): Promise { + this.screenStateService.setEntities(this._toListItems(await this._dossiersService.getDeleted())); + } + + private _canRestore(dossiers = this.screenStateService.selectedEntities): boolean { + return dossiers.reduce((prev, dossier) => prev && dossier.canRestore, true); + } + + private _canRestoreDossier(dossier: Dossier): boolean { + const date = moment(this.getRestoreDate(dossier.softDeletedTime)); + const now = new Date(Date.now()); + + const daysLeft = date.diff(now, 'days'); + const hoursFromNow = date.diff(now, 'hours'); + const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft; + const minutesFromNow = date.diff(now, 'minutes'); + const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft; + + return daysLeft >= 0 && hoursLeft >= 0 && minutesLeft > 0; + } + + private _toListItems(dossiers: Dossier[]): DossierListItem[] { + return dossiers.map(dossier => this._toListItem(dossier)); + } + + private _toListItem(dossier: Dossier): DossierListItem { + return { + ...dossier, + canRestore: this._canRestoreDossier(dossier) + }; + } + + private async _restore(dossiers: DossierListItem[]): Promise { + const dossierIds = dossiers.map(d => d.dossierId); + await this._dossiersService.restore(dossierIds); + this._removeFromList(dossierIds); + } + + private async _hardDelete(dossiers: DossierListItem[]) { + const dossierIds = dossiers.map(d => d.dossierId); + await this._dossiersService.hardDelete(dossierIds); + this._removeFromList(dossierIds); + } + private _removeFromList(ids: string[]): void { const entities = this.entitiesService.all.filter(e => !ids.includes(e.dossierId)); this.entitiesService.setEntities(entities); diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts index 1632d77ee..d270095ce 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts @@ -41,7 +41,7 @@ export class DossierListingScreenComponent extends BaseListingComponent implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach { - readonly itemSize = 95; + readonly itemSize = 85; protected readonly _primaryKey = 'dossierName'; readonly currentUser = this._userService.currentUser; readonly tableHeaderLabel = _('dossier-listing.table-header.title'); diff --git a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html index 447aaded7..d97625d55 100644 --- a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html +++ b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html @@ -15,7 +15,12 @@ -
+
- - B99F3D5E-879A-47E3-A8C7-84877EE418F3 - + diff --git a/apps/red-ui/src/assets/icons/general/put-back.svg b/apps/red-ui/src/assets/icons/general/put-back.svg index 96da3dae5..90c10a820 100644 --- a/apps/red-ui/src/assets/icons/general/put-back.svg +++ b/apps/red-ui/src/assets/icons/general/put-back.svg @@ -1,7 +1,6 @@ - 711C9D82-CAA8-47BE-954A-A9DA22CE85E6 From fa527e69ad01d2c733c27c0205da63d2d1712e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 9 Aug 2021 16:12:07 +0300 Subject: [PATCH 2/4] Dossier templates listing header --- ...-edit-dossier-template-dialog.component.ts | 16 ++--- ...er-templates-listing-screen.component.html | 68 +++++-------------- ...sier-templates-listing-screen.component.ts | 46 +++++++++---- .../table-header/table-header.component.html | 3 + 4 files changed, 60 insertions(+), 73 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts index 3cdb65db1..5d5fdc909 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts @@ -33,8 +33,6 @@ export class AddEditDossierTemplateDialogComponent implements OnInit { private _previousValidFrom: Moment; private _previousValidTo: Moment; - reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId; - constructor( private readonly _appStateService: AppStateService, private readonly _formBuilder: FormBuilder, @@ -68,11 +66,6 @@ export class AddEditDossierTemplateDialogComponent implements OnInit { }); } - async ngOnInit() { - this.availableReportTypes = - (await this._reportTemplateController.getAvailableReportTemplates(this.dossierTemplate?.dossierTemplateId).toPromise()) || []; - } - get changed(): boolean { if (!this.dossierTemplate) return true; @@ -105,6 +98,13 @@ export class AddEditDossierTemplateDialogComponent implements OnInit { return false; } + reportTemplateValueMapper = (reportTemplate: ReportTemplate) => reportTemplate.templateId; + + async ngOnInit() { + this.availableReportTypes = + (await this._reportTemplateController.getAvailableReportTemplates(this.dossierTemplate?.dossierTemplateId).toPromise()) || []; + } + async saveDossierTemplate() { const dossierTemplate = { dossierTemplateId: this.dossierTemplate?.dossierTemplateId, @@ -115,7 +115,7 @@ export class AddEditDossierTemplateDialogComponent implements OnInit { await this._dossierTemplateController.createOrUpdateDossierTemplate(dossierTemplate).toPromise(); await this._appStateService.loadAllDossierTemplates(); await this._appStateService.loadDictionaryData(); - this.dialogRef.close(dossierTemplate); + this.dialogRef.close(true); } private _applyValidityIntervalConstraints(value): boolean { diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html index bf3379f53..16e33115b 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html @@ -8,28 +8,12 @@
-
- - - - {{ - 'dossier-templates-listing.table-header.title' - | translate: { length: (entitiesService.displayedLength$ | async) } - }} - - - - +
-
- -
-
- - - - - - -
-
+
+ + + + diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts index 430ceddf0..b79caca84 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts @@ -20,6 +20,25 @@ export class DossierTemplatesListingScreenComponent extends BaseListingComponent readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; readonly currentUser = this._userService.currentUser; + tableColConfigs: TableColConfig[] = [ + { + label: _('dossier-templates-listing.table-col-names.name'), + withSort: true, + column: 'name' + }, + { label: _('dossier-templates-listing.table-col-names.created-by'), class: 'user-column' }, + { + label: _('dossier-templates-listing.table-col-names.created-on'), + withSort: true, + column: 'dateAdded' + }, + { + label: _('dossier-templates-listing.table-col-names.modified-on'), + withSort: true, + column: 'dateModified' + } + ]; + protected _tableHeaderLabel = _('dossier-templates-listing.table-header.title'); constructor( protected readonly _injector: Injector, @@ -37,35 +56,32 @@ export class DossierTemplatesListingScreenComponent extends BaseListingComponent this.loadDossierTemplatesData(); } - openDeleteTemplatesDialog($event?: MouseEvent) { + openBulkDeleteTemplatesDialog($event?: MouseEvent) { return this._dialogService.openDialog('confirm', $event, null, async () => { - this._loadingService.start(); - await this._dossierTemplateControllerService - .deleteDossierTemplates(this.entitiesService.selected.map(d => d.dossierTemplateId)) - .toPromise(); - this.entitiesService.setSelected([]); - await this._appStateService.loadAllDossierTemplates(); - await this._appStateService.loadDictionaryData(); - this.loadDossierTemplatesData(); + this._loadingService.loadWhile(this._deleteTemplates()); }); } loadDossierTemplatesData() { - this._loadingService.start(); this._appStateService.reset(); this.entitiesService.setEntities(this._appStateService.dossierTemplates); this._loadDossierTemplateStats(); - this._loadingService.stop(); } openAddDossierTemplateDialog() { - this._dialogService.openDialog('addEditDossierTemplate', null, null, async newDossierTemplate => { - if (newDossierTemplate) { - this.loadDossierTemplatesData(); - } + this._dialogService.openDialog('addEditDossierTemplate', null, null, () => { + this.loadDossierTemplatesData(); }); } + private async _deleteTemplates(templateIds: string[] = this.screenStateService.selectedEntities.map(d => d.dossierTemplateId)) { + await this._dossierTemplateControllerService.deleteDossierTemplates(templateIds).toPromise(); + this.screenStateService.setSelectedEntities([]); + await this._appStateService.loadAllDossierTemplates(); + await this._appStateService.loadDictionaryData(); + this.loadDossierTemplatesData(); + } + private _loadDossierTemplateStats() { this.entitiesService.all.forEach(rs => { const dictionaries = this._appStateService.dictionaryData[rs.dossierTemplateId]; diff --git a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html index d97625d55..2b8d9d17d 100644 --- a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html +++ b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html @@ -13,6 +13,9 @@ + + +
Date: Mon, 9 Aug 2021 16:27:21 +0300 Subject: [PATCH 3/4] Fixes --- .../admin/screens/trash/trash-screen.component.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts index 64c049be6..901f0fbb8 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts @@ -68,13 +68,15 @@ export class TrashScreenComponent extends BaseListingComponent private get _canRestoreSelected$(): Observable { return this.screenStateService.selectedEntities$.pipe( - map(entities => entities.length && this._canRestore()), + map(entities => entities.length && this._canRestore(entities)), distinctUntilChanged() ); } async ngOnInit(): Promise { - this._loadingService.loadWhile(this._loadDossiersData()); + this._loadingService.start(); + await this._loadDossiersData(); + this._loadingService.stop(); } getRestoreDate(softDeletedTime: string): string { @@ -82,7 +84,6 @@ export class TrashScreenComponent extends BaseListingComponent } hardDelete(dossiers = this.screenStateService.selectedEntities) { - const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS'); const data = new ConfirmationDialogInput({ title: dossiers.length > 1 ? _('confirmation-dialog.delete-dossier.title-alt') : _('confirmation-dialog.delete-dossier.title'), titleColor: TitleColors.PRIMARY, @@ -91,7 +92,10 @@ export class TrashScreenComponent extends BaseListingComponent confirmationText: _('confirmation-dialog.delete-dossier.confirmation-text'), requireInput: true, denyText: _('confirmation-dialog.delete-dossier.deny-text'), - translateParams: { dossierName: dossiers[0].dossierName, period: period } + translateParams: { + dossierName: dossiers[0].dossierName, + period: this._deleteRetentionHours + } }); this._adminDialogService.openDialog('confirm', null, data, async () => { this._loadingService.loadWhile(this._hardDelete(dossiers)); @@ -106,7 +110,7 @@ export class TrashScreenComponent extends BaseListingComponent this.screenStateService.setEntities(this._toListItems(await this._dossiersService.getDeleted())); } - private _canRestore(dossiers = this.screenStateService.selectedEntities): boolean { + private _canRestore(dossiers: DossierListItem[]): boolean { return dossiers.reduce((prev, dossier) => prev && dossier.canRestore, true); } From dcf62b512e5e566ea49a4c3580ac03a906c995d1 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Mon, 9 Aug 2021 17:23:20 +0300 Subject: [PATCH 4/4] fix rebase --- .../downloads-list-screen.component.html | 2 +- .../downloads-list-screen.component.ts | 8 +-- ...er-templates-listing-screen.component.html | 4 +- ...sier-templates-listing-screen.component.ts | 11 ++-- .../screens/trash/trash-screen.component.html | 6 +-- .../screens/trash/trash-screen.component.ts | 50 ++++++++----------- .../table-header/table-header.component.html | 2 +- .../src/app/modules/shared/pipes/date.pipe.ts | 14 ++---- apps/red-ui/src/app/utils/functions.ts | 18 +++++++ 9 files changed, 58 insertions(+), 57 deletions(-) diff --git a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html index 8007a30fd..96540c481 100644 --- a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html +++ b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html @@ -7,7 +7,7 @@ [bulkActions]="bulkActions" [hasEmptyColumn]="true" [selectionEnabled]="true" - [tableColumnConfigs]="tableColConfigs" + [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel" > diff --git a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts index aaf77cc26..db4e6259c 100644 --- a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts +++ b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts @@ -14,11 +14,11 @@ import { LoadingService } from '@services/loading.service'; providers: [...DefaultListingServices] }) export class DownloadsListScreenComponent extends BaseListingComponent implements OnInit { - readonly circleButtonTypes = CircleButtonTypes; readonly itemSize = 80; protected readonly _primaryKey = 'storageId'; + readonly circleButtonTypes = CircleButtonTypes; readonly tableHeaderLabel = _('downloads-list.table-header.title'); - readonly tableColConfigs: TableColumnConfig[] = [ + readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('downloads-list.table-col-names.name') }, { label: _('downloads-list.table-col-names.size') }, { label: _('downloads-list.table-col-names.date') }, @@ -47,9 +47,9 @@ export class DownloadsListScreenComponent extends BaseListingComponent d.storageId); + const storageIds = (downloads || this.entitiesService.selected).map(d => d.storageId); await this._downloadControllerService.deleteDownload({ storageIds }).toPromise(); - this.screenStateService.setSelectedEntities([]); + this.entitiesService.setSelected([]); await this._loadData(); } diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html index 16e33115b..f956818ae 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html @@ -11,7 +11,7 @@
@@ -94,7 +94,7 @@ [] = [ { label: _('dossier-templates-listing.table-col-names.name'), withSort: true, @@ -38,7 +40,6 @@ export class DossierTemplatesListingScreenComponent extends BaseListingComponent column: 'dateModified' } ]; - protected _tableHeaderLabel = _('dossier-templates-listing.table-header.title'); constructor( protected readonly _injector: Injector, @@ -74,9 +75,9 @@ export class DossierTemplatesListingScreenComponent extends BaseListingComponent }); } - private async _deleteTemplates(templateIds: string[] = this.screenStateService.selectedEntities.map(d => d.dossierTemplateId)) { + private async _deleteTemplates(templateIds: string[] = this.entitiesService.selected.map(d => d.dossierTemplateId)) { await this._dossierTemplateControllerService.deleteDossierTemplates(templateIds).toPromise(); - this.screenStateService.setSelectedEntities([]); + this.entitiesService.setSelected([]); await this._appStateService.loadAllDossierTemplates(); await this._appStateService.loadDictionaryData(); this.loadDossierTemplatesData(); diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html index 49d2932ba..7f8c0234b 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html @@ -8,7 +8,7 @@ @@ -56,7 +56,7 @@
- {{ getRestoreDate(entity.softDeletedTime) | date: 'timeFromNow' }} + {{ entity.restoreDate | date: 'timeFromNow' }}
implements OnInit { - readonly circleButtonTypes = CircleButtonTypes; readonly itemSize = 80; - readonly tableColConfigs: TableColConfig[] = [ + protected readonly _primaryKey = 'dossierName'; + readonly circleButtonTypes = CircleButtonTypes; + readonly tableHeaderLabel = 'trash.table-header.title'; + readonly canRestoreSelected$ = this._canRestoreSelected$; + private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS); + readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('trash.table-col-names.name'), withSort: true, @@ -50,10 +53,6 @@ export class TrashScreenComponent extends BaseListingComponent column: 'softDeletedTime' } ]; - readonly canRestoreSelected$ = this._canRestoreSelected$; - protected readonly _primaryKey = 'dossierName'; - protected readonly _tableHeaderLabel = 'trash.table-header.title'; - private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS); constructor( readonly permissionsService: PermissionsService, @@ -67,8 +66,8 @@ export class TrashScreenComponent extends BaseListingComponent } private get _canRestoreSelected$(): Observable { - return this.screenStateService.selectedEntities$.pipe( - map(entities => entities.length && this._canRestore(entities)), + return this.entitiesService.selected$.pipe( + map(entities => entities.length && !entities.find(dossier => !dossier.canRestore)), distinctUntilChanged() ); } @@ -79,11 +78,11 @@ export class TrashScreenComponent extends BaseListingComponent this._loadingService.stop(); } - getRestoreDate(softDeletedTime: string): string { + private _getRestoreDate(softDeletedTime: string): string { return moment(softDeletedTime).add(this._deleteRetentionHours, 'hours').toISOString(); } - hardDelete(dossiers = this.screenStateService.selectedEntities) { + hardDelete(dossiers = this.entitiesService.selected) { const data = new ConfirmationDialogInput({ title: dossiers.length > 1 ? _('confirmation-dialog.delete-dossier.title-alt') : _('confirmation-dialog.delete-dossier.title'), titleColor: TitleColors.PRIMARY, @@ -102,27 +101,16 @@ export class TrashScreenComponent extends BaseListingComponent }); } - restore(dossiers = this.screenStateService.selectedEntities) { + restore(dossiers = this.entitiesService.selected) { this._loadingService.loadWhile(this._restore(dossiers)); } private async _loadDossiersData(): Promise { - this.screenStateService.setEntities(this._toListItems(await this._dossiersService.getDeleted())); + this.entitiesService.setEntities(this._toListItems(await this._dossiersService.getDeleted())); } - private _canRestore(dossiers: DossierListItem[]): boolean { - return dossiers.reduce((prev, dossier) => prev && dossier.canRestore, true); - } - - private _canRestoreDossier(dossier: Dossier): boolean { - const date = moment(this.getRestoreDate(dossier.softDeletedTime)); - const now = new Date(Date.now()); - - const daysLeft = date.diff(now, 'days'); - const hoursFromNow = date.diff(now, 'hours'); - const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft; - const minutesFromNow = date.diff(now, 'minutes'); - const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft; + private _canRestoreDossier(restoreDate: string): boolean { + const { daysLeft, hoursLeft, minutesLeft } = getLeftDateTime(restoreDate); return daysLeft >= 0 && hoursLeft >= 0 && minutesLeft > 0; } @@ -132,9 +120,11 @@ export class TrashScreenComponent extends BaseListingComponent } private _toListItem(dossier: Dossier): DossierListItem { + const restoreDate = this._getRestoreDate(dossier.softDeletedTime); return { ...dossier, - canRestore: this._canRestoreDossier(dossier) + restoreDate, + canRestore: this._canRestoreDossier(restoreDate) }; } diff --git a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html index 2b8d9d17d..abec8eb74 100644 --- a/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html +++ b/apps/red-ui/src/app/modules/shared/components/table-header/table-header.component.html @@ -19,7 +19,7 @@
0) return this._translateService.instant('time.less-than-an-hour'); diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index 183aae547..1bf96c3b0 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -1,3 +1,5 @@ +import * as moment from 'moment'; + export const FALLBACK_COLOR = '#CCCCCC'; export function groupBy(xs: any[], key: string) { @@ -67,3 +69,19 @@ export function toNumber(string) { return 0; } } + +const HOURS_IN_A_DAY = 24; +const MINUTES_IN_AN_HOUR = 60; + +export function getLeftDateTime(ISOString: string) { + const date = moment(ISOString); + const now = new Date(Date.now()); + + const daysLeft = date.diff(now, 'days'); + const hoursFromNow = date.diff(now, 'hours'); + const hoursLeft = hoursFromNow - HOURS_IN_A_DAY * daysLeft; + const minutesFromNow = date.diff(now, 'minutes'); + const minutesLeft = minutesFromNow - HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * daysLeft; + + return { daysLeft, hoursLeft, minutesLeft }; +}