show time to restore
This commit is contained in:
parent
53d8406c23
commit
7990636066
@ -1,7 +1,10 @@
|
||||
<section>
|
||||
<div class="overlay-shadow"></div>
|
||||
|
||||
<redaction-page-header pageLabel="trash.label" [showCloseButton]="true"></redaction-page-header>
|
||||
<redaction-page-header
|
||||
[pageLabel]="'trash.label' | translate"
|
||||
[showCloseButton]="true"
|
||||
></redaction-page-header>
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container">
|
||||
@ -20,22 +23,20 @@
|
||||
}}
|
||||
</span>
|
||||
|
||||
<ng-container *ngIf="areSomeEntitiesSelected">
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
icon="red:trash"
|
||||
tooltip="trash.bulk.delete"
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
</ng-container>
|
||||
<redaction-circle-button
|
||||
*ngIf="areSomeEntitiesSelected"
|
||||
icon="red:trash"
|
||||
[tooltip]="'trash.bulk.delete' | translate"
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
|
||||
<div class="actions flex-1">
|
||||
<redaction-input-with-action
|
||||
[form]="searchForm"
|
||||
[placeholder]="'trash.search'"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
</div>
|
||||
<!-- <div class="actions flex-1">-->
|
||||
<!-- <redaction-input-with-action-->
|
||||
<!-- [form]="searchForm"-->
|
||||
<!-- [placeholder]="'trash.search' | translate"-->
|
||||
<!-- type="search"-->
|
||||
<!-- ></redaction-input-with-action>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -50,25 +51,25 @@
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="name"
|
||||
label="trash.table-col-names.name"
|
||||
[label]="'trash.table-col-names.name' | translate"
|
||||
></redaction-table-col-name>
|
||||
<redaction-table-col-name
|
||||
class="user-column"
|
||||
label="trash.table-col-names.owner"
|
||||
[label]="'trash.table-col-names.owner' | translate"
|
||||
></redaction-table-col-name>
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="dateDeleted"
|
||||
label="trash.table-col-names.deleted-on"
|
||||
[label]="'trash.table-col-names.deleted-on' | translate"
|
||||
></redaction-table-col-name>
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="timeToRestore"
|
||||
label="trash.table-col-names.time-to-restore"
|
||||
[label]="'trash.table-col-names.time-to-restore' | translate"
|
||||
></redaction-table-col-name>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
@ -88,82 +89,75 @@
|
||||
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="
|
||||
let dw of displayedEntities
|
||||
| sortBy: sortingOption.order:sortingOption.column
|
||||
let entity of displayedEntities
|
||||
| sortBy: sortingOption.order:sortingOption.column;
|
||||
trackBy: trackById
|
||||
"
|
||||
class="table-item"
|
||||
>
|
||||
<div (click)="toggleEntitySelected($event, dw)" class="selection-column">
|
||||
<div (click)="toggleEntitySelected($event, entity)" class="selection-column">
|
||||
<redaction-round-checkbox
|
||||
[active]="isSelected(dw)"
|
||||
[active]="isSelected(entity)"
|
||||
></redaction-round-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="filename">
|
||||
<div
|
||||
class="table-item-title heading"
|
||||
[matTooltip]="dw.dossierName"
|
||||
[matTooltip]="entity.dossierName"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
{{ dw.dossierName }}
|
||||
{{ entity.dossierName }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
{{ getDossierTemplate(dw).name }}
|
||||
{{ getDossierTemplate(entity.dossierTemplateId).name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
{{ dw.files.length }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ dw.totalNumberOfPages }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
{{ dw.numberOfMembers }}
|
||||
{{ entity.memberIds.length }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ dw.dossier.date | date: 'mediumDate' }}
|
||||
{{ entity.date | date: 'mediumDate' }}
|
||||
</div>
|
||||
<div *ngIf="dw.dossier.dueDate">
|
||||
<div *ngIf="entity.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
{{ dw.dossier.dueDate | date: 'mediumDate' }}
|
||||
{{ entity.dueDate | date: 'mediumDate' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="user-column">
|
||||
<redaction-initials-avatar
|
||||
[userId]="dw.dossier.ownerId"
|
||||
[userId]="entity.ownerId"
|
||||
[withName]="true"
|
||||
></redaction-initials-avatar>
|
||||
</div>
|
||||
|
||||
<div class="small-label">
|
||||
{{ dw.dossierDate | date: 'd MMM. yyyy' }}
|
||||
{{ entity.softDeletedTime | date: 'd MMM. yyyy' }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="small-label">
|
||||
{{ dw.dossier.date | date: 'd MMM. yyyy' }}
|
||||
{{ getRestoreDate(entity.softDeletedTime) | date: 'timeFromNow' }}
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isManager()"
|
||||
(action)="restore(entity)"
|
||||
icon="red:undo"
|
||||
tooltip="trash.action.restore"
|
||||
[tooltip]="'trash.action.restore' | translate"
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isManager()"
|
||||
(action)="hardDelete(entity)"
|
||||
icon="red:trash"
|
||||
tooltip="trash.action.delete"
|
||||
[tooltip]="'trash.action.delete' | translate"
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
|
||||
@ -1,42 +1,74 @@
|
||||
import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { DossierTemplateModel } from '@redaction/red-ui-http';
|
||||
import { Dossier, DossierControllerService, DossierTemplateModel } from '@redaction/red-ui-http';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
||||
import * as moment from 'moment';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
templateUrl: './trash-screen.component.html',
|
||||
styleUrls: ['./trash-screen.component.scss']
|
||||
})
|
||||
export class TrashScreenComponent extends BaseListingComponent<DossierWrapper> implements OnInit {
|
||||
export class TrashScreenComponent extends BaseListingComponent<Dossier> implements OnInit {
|
||||
readonly itemSize = 85;
|
||||
private readonly _deleteRetentionHours = this._appConfigService.getConfig(
|
||||
AppConfigKey.DELETE_RETENTION_HOURS
|
||||
);
|
||||
|
||||
protected readonly _searchKey = 'name';
|
||||
protected readonly _searchKey = 'dossierName';
|
||||
protected readonly _selectionKey = 'dossierId';
|
||||
protected readonly _sortKey = 'dossier-listing';
|
||||
|
||||
constructor(
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
protected readonly _injector: Injector
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _dossierControllerService: DossierControllerService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _appConfigService: AppConfigService,
|
||||
private readonly _translateService: TranslateService
|
||||
) {
|
||||
super(_injector);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadDossierTemplatesData();
|
||||
async ngOnInit(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
await this.loadDossierTemplatesData();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
loadDossierTemplatesData() {
|
||||
this.allEntities = this._appStateService.allDossiers;
|
||||
async loadDossierTemplatesData(): Promise<void> {
|
||||
this.allEntities = await this._dossierControllerService.getDeletedDossiers().toPromise();
|
||||
console.log(this.allEntities);
|
||||
this._executeSearchImmediately();
|
||||
}
|
||||
|
||||
getDossierTemplate(dw: DossierWrapper): DossierTemplateModel {
|
||||
return this._appStateService.getDossierTemplateById(dw.dossier.dossierTemplateId);
|
||||
getDossierTemplate(dossierTemplateId: string): DossierTemplateModel {
|
||||
return this._appStateService.getDossierTemplateById(dossierTemplateId);
|
||||
}
|
||||
|
||||
getRestoreDate(softDeletedTime: string) {
|
||||
return moment(softDeletedTime).add(5, 'hours').format();
|
||||
}
|
||||
|
||||
async restore(dossier: Dossier) {
|
||||
this._loadingService.start();
|
||||
await this._dossierControllerService.restoreDossiers([dossier.dossierId]).toPromise();
|
||||
this.allEntities = this.allEntities.filter(e => e !== dossier);
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
async hardDelete(dossier: Dossier) {
|
||||
this._loadingService.start();
|
||||
await this._dossierControllerService.hardDeleteDossiers([dossier.dossierId]).toPromise();
|
||||
this.allEntities = this.allEntities.filter(e => e !== dossier);
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
trackById(index: number, dossier: Dossier) {
|
||||
return dossier.dossierId;
|
||||
}
|
||||
}
|
||||
|
||||
62
apps/red-ui/src/app/modules/shared/pipes/date.pipe.ts
Normal file
62
apps/red-ui/src/app/modules/shared/pipes/date.pipe.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core';
|
||||
import * as moment from 'moment';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DatePipe as BaseDatePipe } from '@angular/common';
|
||||
|
||||
const HOURS_IN_A_DAY = 24;
|
||||
const MINUTES_IN_AN_HOUR = 60;
|
||||
|
||||
@Pipe({
|
||||
name: 'date'
|
||||
})
|
||||
export class DatePipe extends BaseDatePipe implements PipeTransform {
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) private readonly _locale: string,
|
||||
private readonly _translateService: TranslateService
|
||||
) {
|
||||
super(_locale);
|
||||
}
|
||||
|
||||
transform(value: null | undefined, format?: string, timezone?: string, locale?: string): null;
|
||||
transform(
|
||||
value: Date | string | number | null | undefined,
|
||||
format?: string,
|
||||
timezone?: string,
|
||||
locale?: string
|
||||
): string | null;
|
||||
transform(value: any, format?: string, timezone?: string, locale?: string): string {
|
||||
if (format === 'timeFromNow') return this._getTimeFromNow(value);
|
||||
return super.transform(value, format, timezone, locale);
|
||||
}
|
||||
|
||||
private _getTimeFromNow(item: string) {
|
||||
const date = moment(item);
|
||||
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;
|
||||
|
||||
if (daysLeft === 0 && hoursLeft === 0 && minutesLeft > 0)
|
||||
return this._translate('time.less-than-an-hour');
|
||||
|
||||
const hoursSuffix = this._translate(`time.hour${hoursLeft === 1 ? '' : 's'}`);
|
||||
const hoursDisplay = `${hoursLeft} ${hoursSuffix}`;
|
||||
|
||||
if (daysLeft === 0 && hoursLeft > 0) return hoursDisplay;
|
||||
|
||||
const daysSuffix = this._translate(`time.day${daysLeft === 1 ? '' : 's'}`);
|
||||
const daysDisplay = `${daysLeft} ${daysSuffix}`;
|
||||
|
||||
if (daysLeft > 0 && hoursLeft > 0) return `${daysDisplay} ${hoursDisplay}`;
|
||||
if (daysLeft > 0) return daysDisplay;
|
||||
|
||||
return this._translate(`time.no-time-left`);
|
||||
}
|
||||
|
||||
private _translate(value: string, params?: { [key: string]: string }) {
|
||||
return this._translateService.instant(value, params);
|
||||
}
|
||||
}
|
||||
@ -38,6 +38,7 @@ import { PopupFilterComponent } from '@shared/components/filters/popup-filter/po
|
||||
import { AssignUserDropdownComponent } from './components/assign-user-dropdown/assign-user-dropdown.component';
|
||||
import { InputWithActionComponent } from '@shared/components/input-with-action/input-with-action.component';
|
||||
import { PageHeaderComponent } from './components/page-header/page-header.component';
|
||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||
|
||||
const buttons = [
|
||||
ChevronButtonComponent,
|
||||
@ -75,6 +76,7 @@ const components = [
|
||||
|
||||
const utils = [
|
||||
HumanizePipe,
|
||||
DatePipe,
|
||||
SyncWidthDirective,
|
||||
HasScrollbarDirective,
|
||||
NavigateLastDossiersScreenDirective
|
||||
|
||||
@ -1404,5 +1404,13 @@
|
||||
"text-placeholder": "Enter text"
|
||||
},
|
||||
"title": "Watermark"
|
||||
},
|
||||
"time": {
|
||||
"no-time-left": "Time to restore already passed",
|
||||
"less-than-an-hour": "< 1 hour",
|
||||
"hour": "hour",
|
||||
"hours": "hours",
|
||||
"day": "day",
|
||||
"days": "days"
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,10 +19,12 @@ export interface Dossier {
|
||||
dossierTemplateId?: string;
|
||||
downloadFileTypes?: Array<Dossier.DownloadFileTypesEnum>;
|
||||
dueDate?: string;
|
||||
hardDeletedTime?: string;
|
||||
memberIds?: Array<string>;
|
||||
ownerId?: string;
|
||||
reportTemplateIds?: Array<string>;
|
||||
reportTypes?: Array<Dossier.ReportTypesEnum>;
|
||||
softDeletedTime?: string;
|
||||
status?: Dossier.StatusEnum;
|
||||
watermarkEnabled?: boolean;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user