Downloads & trash refactor

This commit is contained in:
Adina Țeudan 2021-10-01 15:09:23 +03:00
parent ef5e5ded18
commit 0f93837529
7 changed files with 113 additions and 153 deletions

View File

@ -7,7 +7,6 @@
<div class="red-content-inner">
<div class="content-container">
<iqser-table
[actionsTemplate]="actionsTemplate"
[bulkActions]="bulkActions"
[itemSize]="80"
[noDataText]="'downloads-list.no-data.title' | translate"
@ -29,55 +28,51 @@
></iqser-circle-button>
</ng-template>
<ng-template #filenameTemplate let-download="entity">
<div class="cell">
<div [class.no-bold]="download.lastDownload" class="table-item-title heading">
{{ download.filename }}
<ng-template #tableItemTemplate let-download="entity">
<div>
<div class="cell">
<div [class.no-bold]="download.lastDownload" class="table-item-title heading">
{{ download.filename }}
</div>
</div>
<div class="cell">
<div class="small-label">
{{ download.size }}
</div>
</div>
<div class="cell">
<div class="small-label">
{{ download.creationDate | date: 'd MMM. yyyy, hh:mm a' }}
</div>
</div>
<div class="cell">
<div class="small-label">
{{ download.status }}
</div>
</div>
<div></div>
<div [class.active]="download.inProgress" class="action-buttons">
<iqser-circle-button
(action)="downloadItem(download)"
*ngIf="download.status === 'READY' && !download.inProgress"
[tooltip]="'downloads-list.actions.download' | translate"
[type]="circleButtonTypes.dark"
icon="red:download"
></iqser-circle-button>
<iqser-circle-button
(action)="deleteItems([download])"
[tooltip]="'downloads-list.actions.delete' | translate"
[type]="circleButtonTypes.dark"
icon="red:trash"
></iqser-circle-button>
<mat-spinner *ngIf="download.inProgress" diameter="15"></mat-spinner>
</div>
</div>
</ng-template>
<ng-template #sizeTemplate let-download="entity">
<div class="cell">
<div class="small-label">
{{ download.size }}
</div>
</div>
</ng-template>
<ng-template #creationDateTemplate let-download="entity">
<div class="cell">
<div class="small-label">
{{ download.creationDate | date: 'd MMM. yyyy, hh:mm a' }}
</div>
</div>
</ng-template>
<ng-template #statusTemplate let-download="entity">
<div class="cell">
<div class="small-label">
{{ download.status }}
</div>
</div>
</ng-template>
<ng-template #actionsTemplate let-download="entity">
<div [class.active]="download.inProgress" class="action-buttons">
<iqser-circle-button
(action)="downloadItem(download)"
*ngIf="download.status === 'READY' && !download.inProgress"
[tooltip]="'downloads-list.actions.download' | translate"
[type]="circleButtonTypes.dark"
icon="red:download"
></iqser-circle-button>
<iqser-circle-button
(action)="deleteItems([download])"
[tooltip]="'downloads-list.actions.delete' | translate"
[type]="circleButtonTypes.dark"
icon="red:trash"
></iqser-circle-button>
<mat-spinner *ngIf="download.inProgress" diameter="15"></mat-spinner>
</div>
</ng-template>

View File

@ -1,4 +1,4 @@
import { Component, forwardRef, Injector, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { Component, forwardRef, Injector, OnInit } from '@angular/core';
import { FileDownloadService } from '@upload-download/services/file-download.service';
import { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper';
import { DownloadControllerService } from '@redaction/red-ui-http';
@ -16,11 +16,12 @@ import { RouterHistoryService } from '@services/router-history.service';
export class DownloadsListScreenComponent extends ListingComponent<DownloadStatusWrapper> implements OnInit {
readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('downloads-list.table-header.title');
tableColumnConfigs: TableColumnConfig<DownloadStatusWrapper>[];
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
@ViewChild('sizeTemplate', { static: true }) sizeTemplate: TemplateRef<never>;
@ViewChild('creationDateTemplate', { static: true }) creationDateTemplate: TemplateRef<never>;
@ViewChild('statusTemplate', { static: true }) statusTemplate: TemplateRef<never>;
readonly tableColumnConfigs: TableColumnConfig<DownloadStatusWrapper>[] = [
{ label: _('downloads-list.table-col-names.name'), width: '2fr' },
{ label: _('downloads-list.table-col-names.size') },
{ label: _('downloads-list.table-col-names.date') },
{ label: _('downloads-list.table-col-names.status') }
];
constructor(
protected readonly _injector: Injector,
@ -33,7 +34,6 @@ export class DownloadsListScreenComponent extends ListingComponent<DownloadStatu
}
async ngOnInit() {
this._configureTableColumns();
this._loadingService.start();
await this._loadData();
this.addSubscription = timer(0, 5000).subscribe(async () => {
@ -50,15 +50,6 @@ export class DownloadsListScreenComponent extends ListingComponent<DownloadStatu
this._loadingService.loadWhile(this._deleteItems(downloads));
}
private _configureTableColumns() {
this.tableColumnConfigs = [
{ label: _('downloads-list.table-col-names.name'), width: '2fr', template: this.filenameTemplate },
{ label: _('downloads-list.table-col-names.size'), template: this.sizeTemplate },
{ label: _('downloads-list.table-col-names.date'), template: this.creationDateTemplate },
{ label: _('downloads-list.table-col-names.status'), template: this.statusTemplate }
];
}
private async _deleteItems(downloads?: DownloadStatusWrapper[]) {
const storageIds = (downloads || this.entitiesService.selected).map(d => d.storageId);
await this._downloadControllerService.deleteDownload({ storageIds }).toPromise();

View File

@ -40,62 +40,58 @@
></iqser-circle-button>
</ng-template>
<ng-template #filenameTemplate let-entity="entity">
<div class="cell filename">
<div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above">
{{ entity.dossierName }}
<ng-template #tableItemTemplate let-entity="entity">
<div>
<div class="cell filename">
<div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above">
{{ entity.dossierName }}
</div>
<div class="small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:user"></mat-icon>
{{ entity.memberIds.length }}
</div>
<div>
<mat-icon svgIcon="red:calendar"></mat-icon>
{{ entity.date | date: 'mediumDate' }}
</div>
<div *ngIf="entity.dueDate">
<mat-icon svgIcon="red:lightning"></mat-icon>
{{ entity.dueDate | date: 'mediumDate' }}
</div>
</div>
</div>
<div class="small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:user"></mat-icon>
{{ entity.memberIds.length }}
<div class="cell user-column">
<redaction-initials-avatar [userId]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
</div>
<div class="cell">
<span class="small-label">
{{ entity.softDeletedTime | date: 'd MMM. yyyy, hh:mm a' }}
</span>
</div>
<div class="cell">
<div class="small-label">
{{ entity.restoreDate | date: 'timeFromNow' }}
</div>
<div>
<mat-icon svgIcon="red:calendar"></mat-icon>
{{ entity.date | date: 'mediumDate' }}
</div>
<div *ngIf="entity.dueDate">
<mat-icon svgIcon="red:lightning"></mat-icon>
{{ entity.dueDate | date: 'mediumDate' }}
<div class="action-buttons">
<iqser-circle-button
(action)="restore([entity])"
*ngIf="entity.canRestore"
[tooltip]="'trash.action.restore' | translate"
[type]="circleButtonTypes.dark"
icon="red:put-back"
></iqser-circle-button>
<iqser-circle-button
(action)="hardDelete([entity])"
[tooltip]="'trash.action.delete' | translate"
[type]="circleButtonTypes.dark"
icon="red:trash"
></iqser-circle-button>
</div>
</div>
</div>
</ng-template>
<ng-template #ownerTemplate let-entity="entity">
<div class="cell user-column">
<redaction-initials-avatar [userId]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
</div>
</ng-template>
<ng-template #deletedTimeTemplate let-entity="entity">
<div class="cell">
<span class="small-label">
{{ entity.softDeletedTime | date: 'd MMM. yyyy, hh:mm a' }}
</span>
</div>
</ng-template>
<ng-template #restoreDateTemplate let-entity="entity">
<div class="cell">
<div class="small-label">
{{ entity.restoreDate | date: 'timeFromNow' }}
</div>
<div class="action-buttons">
<iqser-circle-button
(action)="restore([entity])"
*ngIf="entity.canRestore"
[tooltip]="'trash.action.restore' | translate"
[type]="circleButtonTypes.dark"
icon="red:put-back"
></iqser-circle-button>
<iqser-circle-button
(action)="hardDelete([entity])"
[tooltip]="'trash.action.delete' | translate"
[type]="circleButtonTypes.dark"
icon="red:trash"
></iqser-circle-button>
</div>
</div>
</ng-template>

View File

@ -0,0 +1,3 @@
.stats-subtitle {
margin-top: 4px;
}

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core';
import { IDossier } from '@redaction/red-ui-http';
import {
CircleButtonTypes,
@ -35,11 +35,12 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('trash.table-header.title');
readonly canRestoreSelected$ = this._canRestoreSelected$;
tableColumnConfigs: TableColumnConfig<DossierListItem>[];
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
@ViewChild('ownerTemplate', { static: true }) ownerTemplate: TemplateRef<never>;
@ViewChild('deletedTimeTemplate', { static: true }) deletedTimeTemplate: TemplateRef<never>;
@ViewChild('restoreDateTemplate', { static: true }) restoreDateTemplate: TemplateRef<never>;
readonly tableColumnConfigs: TableColumnConfig<DossierListItem>[] = [
{ label: _('trash.table-col-names.name'), sortByKey: 'searchKey' },
{ label: _('trash.table-col-names.owner'), class: 'user-column' },
{ label: _('trash.table-col-names.deleted-on'), sortByKey: 'softDeletedTime' },
{ label: _('trash.table-col-names.time-to-restore'), sortByKey: 'softDeletedTime' }
];
constructor(
protected readonly _injector: Injector,
@ -62,7 +63,6 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
disabledFn = (dossier: DossierListItem) => !dossier.canRestore;
async ngOnInit(): Promise<void> {
this._configureTableColumns();
this._loadingService.start();
await this._loadDossiersData();
this.sortingService.setSortingOption({
@ -95,31 +95,6 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
this._loadingService.loadWhile(this._restore(dossiers));
}
private _configureTableColumns() {
this.tableColumnConfigs = [
{
label: _('trash.table-col-names.name'),
sortByKey: 'searchKey',
template: this.filenameTemplate
},
{
label: _('trash.table-col-names.owner'),
class: 'user-column',
template: this.ownerTemplate
},
{
label: _('trash.table-col-names.deleted-on'),
sortByKey: 'softDeletedTime',
template: this.deletedTimeTemplate
},
{
label: _('trash.table-col-names.time-to-restore'),
sortByKey: 'softDeletedTime',
template: this.restoreDateTemplate
}
];
}
private _getRestoreDate(softDeletedTime: string): string {
return moment(softDeletedTime).add(this._configService.values.DELETE_RETENTION_HOURS, 'hours').toISOString();
}

View File

@ -110,7 +110,7 @@ export class ConfigService {
{
label: fileStatusTranslations[FileStatuses.APPROVED],
enterFn: this._approveFn(reloadDossiers),
enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file),
enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file) && file.canBeApproved,
key: FileStatuses.APPROVED,
color: '#48C9F7'
}

@ -1 +1 @@
Subproject commit 85d22fbcc9b3673d11dbf542e3b6ee16c7791d84
Subproject commit 551db967e2d747932579464f00e4e497c91dc628