angular/projects/researchdatabox/deleted-records/src/app/deleted-records.component.ts
Restore deleted records Component
selector | deleted-records |
styleUrls | ./deleted-records.component.scss |
templateUrl | ./deleted-records.component.html |
Properties |
|
Methods |
|
constructor(loggerService: LoggerService, recordService: RecordService, configService: ConfigService, translationService: TranslationService, elementRef: ElementRef)
|
||||||||||||||||||
Parameters :
|
Public Async confirmDestroyRecordModal | ||||||
confirmDestroyRecordModal(event: any)
|
||||||
Parameters :
Returns :
any
|
Public Async filter | ||||||||
filter(event?: any)
|
||||||||
Apply the filters.
Parameters :
Returns :
any
|
Private getConfigProp |
getConfigProp(name: string, defaultValue: any)
|
Returns :
any
|
Public getCurrentPage |
getCurrentPage()
|
Get the data for the current page. Used by RecordTableComponent.
Returns :
ReportResultDto
|
Private Async getDeletedRecords |
getDeletedRecords()
|
Returns :
Promise<ReportResultDto>
|
Private getParams |
getParams()
|
Returns :
any
|
Public Async gotoPage | ||||||||
gotoPage(pageNum: number)
|
||||||||
Load the data for the given page. Used by RecordTableComponent.
Parameters :
Returns :
Promise<RecordPageDto>
|
Public Async headerSortChanged |
headerSortChanged(event: any, data: any)
|
Returns :
any
|
Public hideDestroyRecordModal |
hideDestroyRecordModal()
|
Returns :
void
|
Protected Async initComponent |
initComponent()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:208
|
Returns :
Promise<void>
|
Public onDestroyRecordModalHidden |
onDestroyRecordModalHidden()
|
Returns :
void
|
Public Async recordTableAction |
recordTableAction(event: any, data: any, actionName: string)
|
Returns :
any
|
Public showDestroyRecordModal |
showDestroyRecordModal()
|
Returns :
void
|
getInitSubject |
getInitSubject()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:71
|
For those interested in the init from RXJS-land. Note that it returns a BehaviorSubject instance, and will have an initial value of false, so process the return value as needed.
Returns :
Subject<any>
|
isInitializing |
isInitializing()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:95
|
Main flag to indicate the init status
Returns :
boolean
|
ngOnInit |
ngOnInit()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:50
|
Returns :
void
|
Async waitForDeps |
waitForDeps()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:78
|
Wait for dependencies to initialise
Returns :
Promise<any>
|
Async waitForInit |
waitForInit()
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:89
|
For those interested in the init from the Promise-land
Returns :
Promise<any>
|
appName |
Type : string
|
Default value : 'deleted-records'
|
currentDestroyRecordModalOid |
Type : string | undefined
|
currentPageNumber |
Type : number
|
Default value : 1
|
deletedRecordsResult |
Type : ReportResultDto
|
Default value : null as any
|
Optional destroyRecordModal |
Type : ModalDirective
|
Decorators :
@ViewChild('destroyRecordModal')
|
dropDownProperties |
Type : literal type
|
Default value : {
'recordType': [{title: 'All', value: ''}]
}
|
filterParams |
Type : any
|
Default value : {}
|
initTracker |
Type : any
|
Default value : {resultsReturned: false}
|
isDestroyRecordModalShown |
Type : boolean
|
Default value : false
|
optTemplateData |
Type : any
|
Default value : {}
|
paginationMaxSize |
Type : number
|
Default value : 10
|
recordsPerPage |
Type : number
|
Default value : 10
|
showActions |
Type : []
|
Default value : [
{name: 'restore', classes: 'btn-primary', label: 'action-restore'},
{name: 'destroy', classes: 'btn-danger', label: 'action-destroy'},
]
|
sort |
Type : string | undefined
|
Protected sysConfig |
Type : any
|
Protected brandingAndPortalUrl |
Type : string
|
Default value : ''
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:42
|
Private filterFn |
Default value : function(initStat: boolean) { return initStat; }
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:40
|
Protected initDependencies |
Type : Initable[]
|
Default value : []
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:39
|
Protected initSubject |
Type : BehaviorSubject<any>
|
Default value : new BehaviorSubject(false)
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:38
|
Protected isReady |
Type : boolean
|
Default value : false
|
Inherited from
BaseComponent
|
Defined in
BaseComponent:37
|
import { Component, Inject, ElementRef, ViewChild } from '@angular/core';
import { ConfigService, LoggerService, TranslationService, RecordService, BaseComponent, RecordSource } from '@researchdatabox/portal-ng-common';
import { RecordPropViewMetaDto, ReportResultDto, RecordPageDto } from '@researchdatabox/sails-ng-common';
import { isEmpty as _isEmpty, set as _set, get as _get, isUndefined as _isUndefined } from 'lodash-es';
import { ReportFilterDto } from "@researchdatabox/sails-ng-common/dist/report.model";
import { RecordResponseTable } from "../../../portal-ng-common/src/lib/dashboard-models";
import { ModalDirective } from "ngx-bootstrap/modal";
/**
* Restore deleted records Component
*/
@Component({
selector: 'deleted-records',
templateUrl: './deleted-records.component.html',
styleUrls: ['./deleted-records.component.scss']
})
export class DeletedRecordsComponent extends BaseComponent implements RecordSource {
appName: string = 'deleted-records';
// Internal properties
protected sysConfig: any;
// State tracking
initTracker: any = {resultsReturned: false};
// Record filter properties
recordsPerPage: number = 10;
paginationMaxSize: number = 10;
currentPageNumber: number = 1;
filters: ReportFilterDto[] = [
{
paramName: "title",
type: "text",
message: "Filter by title",
property: "title",
},
{
paramName: "recordType",
type: 'drop-down',
message: "Filter by record type",
property: '',
},
];
sort: string | undefined;
dropDownProperties: { [key: string]: { title: string, value: string }[] } = {
'recordType': [{title: 'All', value: ''}]
};
// Filter values entered by user
filterParams: any = {};
// Record table properties
tableHeaders: RecordPropViewMetaDto[] = [
{
label: "deleted-records-results-table-header-title",
property: "title",
template: "${ data.title }",
hide: false,
multivalue: false
},
{
label: "deleted-records-results-table-header-created-date",
property: "dateCreated",
template: "${ DateTime.fromISO(data.dateCreated).toFormat('dd/MM/yyyy hh:mm a') }",
hide: false,
multivalue: false
},
{
label: "deleted-records-results-table-header-modified-date",
property: "dateModified",
template: "${ DateTime.fromISO(data.dateModified).toFormat('dd/MM/yyyy hh:mm a') }",
hide: false,
multivalue: false
},
{
label: "deleted-records-results-table-header-deleted-date",
property: "dateDeleted",
template: "${ DateTime.fromISO(data.dateDeleted).toFormat('dd/MM/yyyy hh:mm a') }",
hide: false,
multivalue: false
},
];
optTemplateData: any = {};
showActions = [
{name: 'restore', classes: 'btn-primary', label: 'action-restore'},
{name: 'destroy', classes: 'btn-danger', label: 'action-destroy'},
]
// Record list data
deletedRecordsResult: ReportResultDto = null as any;
// destroy record confirm modal
currentDestroyRecordModalOid: string | undefined;
isDestroyRecordModalShown: boolean = false;
@ViewChild('destroyRecordModal') destroyRecordModal?: ModalDirective;
constructor(
@Inject(LoggerService) private loggerService: LoggerService,
@Inject(RecordService) protected recordService: RecordService,
@Inject(ConfigService) private configService: ConfigService,
@Inject(TranslationService) private translationService: TranslationService,
@Inject(ElementRef) elementRef: ElementRef
) {
super();
this.initDependencies = [this.translationService, this.recordService];
this.loggerService.debug(`'${this.appName}' waiting for deps to init...`);
}
/**
* Get the data for the current page.
* Used by RecordTableComponent.
*/
public getCurrentPage() {
return this.deletedRecordsResult;
}
/**
* Load the data for the given page.
* Used by RecordTableComponent.
* @param pageNum Load the data for this page nnumber.
*/
public async gotoPage(pageNum: number): Promise<RecordPageDto> {
this.currentPageNumber = pageNum;
this.initTracker.resultsReturned = false;
this.deletedRecordsResult = await this.getDeletedRecords();
this.initTracker.resultsReturned = true;
return this.deletedRecordsResult;
}
/**
* Apply the filters.
* @param event The click event data.
*/
public async filter(event?: any) {
await this.gotoPage(1);
}
public async headerSortChanged(event: any, data: any) {
this.sort = `${event.variable}:${event.sort === 'desc' ? '-1' : '1'}`;
await this.gotoPage(1);
}
public async recordTableAction(event: any, data: any, actionName: string) {
const oid = data.oid;
if (actionName === 'restore') {
const result = await this.recordService.restoreDeletedRecord(oid);
this.loggerService.debug(`Record table action ${actionName} data ${JSON.stringify(data)} result ${JSON.stringify(result)}.`);
await this.gotoPage(this.currentPageNumber);
} else if (actionName === 'destroy') {
this.currentDestroyRecordModalOid = oid;
this.showDestroyRecordModal();
} else {
this.loggerService.error(`Unknown record table action name '${actionName}' data ${JSON.stringify(data)}.`);
return;
}
}
public showDestroyRecordModal(): void {
this.isDestroyRecordModalShown = true;
this.destroyRecordModal?.show();
}
public hideDestroyRecordModal(): void {
this.destroyRecordModal?.hide();
this.currentDestroyRecordModalOid = undefined;
}
public onDestroyRecordModalHidden(): void {
this.isDestroyRecordModalShown = false;
}
public async confirmDestroyRecordModal(event: any) {
if (_isUndefined(this.currentDestroyRecordModalOid)) {
this.loggerService.error("Record oid was not set so cannot destroy record.");
return;
}
const oid = this.currentDestroyRecordModalOid;
const result = await this.recordService.destroyDeletedRecord(oid);
this.loggerService.debug(`Record table action destroy result ${JSON.stringify(result)}.`);
this.destroyRecordModal?.hide();
this.currentDestroyRecordModalOid = undefined;
await this.gotoPage(this.currentPageNumber);
}
protected async initComponent(): Promise<void> {
this.sysConfig = await this.configService.getConfig();
// Initialise settings from sys config
this.recordsPerPage = this.getConfigProp('recordsPerPage', this.recordsPerPage);
this.paginationMaxSize = this.getConfigProp('paginationMaxSize', this.paginationMaxSize);
// Additional data required for the record-table component
this.brandingAndPortalUrl = this.recordService.brandingAndPortalUrl;
_set(this.optTemplateData, 'brandingAndPortalUrl', this.brandingAndPortalUrl);
// populate record types
const recordTypes: {
name: string;
packageType: string;
searchFilters: [];
searchable: boolean
}[] = await this.recordService.getAllTypes();
recordTypes.forEach(recordType => {
this.dropDownProperties['recordType'].push({
title: recordType.name,
value: recordType.name,
});
});
// Load the first page of records
this.gotoPage(1);
this.loggerService.debug(`'${this.appName}' ready!`);
}
private async getDeletedRecords(): Promise<ReportResultDto> {
const params = this.getParams();
const paramText: string = _get(params, 'title', '')?.toString().trim();
const paramRecordType: string = _get(params, 'recordType', '');
const recordType = paramRecordType;
const filterString = paramText || '';
const filterMode = 'regex';
const workflowState = '';
const packageType = undefined;
const filterFields = 'title';
const records: RecordResponseTable = await this.recordService.getDeletedRecords(
recordType, workflowState, this.currentPageNumber, packageType, this.sort, filterFields, filterString, filterMode);
return {
recordsPerPage: this.recordsPerPage,
records: records.items,
total: records.totalItems,
pageNum: this.currentPageNumber,
};
}
private getParams() {
const params: any = {};
for (let filter of this.filters) {
let paramValue = this.filterParams[filter.paramName];
if (!_isEmpty(paramValue)) {
params[filter.paramName] = paramValue;
}
}
return params;
}
private getConfigProp(name: string, defaultValue: any) {
return ConfigService._getAppConfigProperty(this.sysConfig, this.appName, name, defaultValue);
}
}
<ng-container *ngIf="isReady">
<div class="row">
<div class="col-xs-12">
<h1 class="text-center" >
{{ 'deleted-records-heading' | i18next }}
</h1>
</div>
</div>
<!-- Render the filter UI elements -->
<div class="row" *ngIf="filters != null">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="text-center h4-header mb-2">
{{ 'deleted-records-filters-heading' | i18next }}
</div>
</div>
<ng-container *ngFor="let filter of filters">
<!-- Text filter -->
<div *ngIf="filter.type == 'text'" class="row">
<div class="col-md-2"></div>
<div class="col-xs-2">
<label [for]="filter.paramName" class="form-label">{{filter.message}}</label>
</div>
<div class="col-xs-6">
<input [id]="filter.paramName" type="text" class="form-control" [(ngModel)]="filterParams[ filter['paramName']]">
</div>
<div class="col-md-2"></div>
</div>
<!-- Dropdown filter -->
<div *ngIf="filter.type == 'drop-down'" class="row mt-2">
<div class="col-md-2"></div>
<div class="col-xs-2">
<label [for]="filter.paramName" class="form-label">{{filter.message}}</label>
</div>
<div class="col-xs-6">
<select [id]="filter.paramName" class="form-control" [(ngModel)]="filterParams[ filter['paramName']]">
<option *ngFor="let item of dropDownProperties[filter['paramName']]; first as isFirst" [value]="item.value" [defaultSelected]="isFirst">
{{ item.title }}
</option>
</select>
</div>
<div class="col-md-2"></div>
</div>
</ng-container>
<div class="row">
<div class="col-xs-2"></div>
<div class="col-xs-8 pt-2 text-end">
<a class="btn btn-large btn-primary" (click)="filter()">
<span class="glyphicon glyphicon-search"></span>
{{ 'deleted-records-filter-button' | i18next }}
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Result overview -->
<div class="row" *ngIf="initTracker && initTracker.resultsReturned">
<div class="col-xs-2">
<span *ngIf="initTracker.resultsReturned == false">
<span class="fa fa-spinner fa-spin fa-fw"></span>
{{ 'deleted-records-retrieving-results' | i18next }}
</span>
<span *ngIf="initTracker.resultsReturned == true"
[innerHTML]='"deleted-records-results-returned" | i18next: {count: deletedRecordsResult.total }'>
</span>
</div>
<div class="col-xs-8"></div>
<div class="col-xs-2"></div>
</div>
<!-- Result details -->
<record-table
[columnConfig]="tableHeaders"
[dataSource]="this"
[optTemplateData]="optTemplateData"
[paginationItemsPerPage]="recordsPerPage"
[paginationMaxSize]="paginationMaxSize"
[showActions]="showActions"
[enableSort]="true"
[enableActions]="true">
</record-table>
<!-- Modal -->
<div *ngIf="isDestroyRecordModalShown"
[config]="{backdrop: 'static', show: true}"
(onHidden)="onDestroyRecordModalHidden()"
bsModal
#destroyRecordModal="bs-modal"
class="modal fade"
tabindex="-1"
role="dialog"
aria-labelledby="deleted-records-confirm-modal-label">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-header">
<span class="modal-title h4-header" id="deleted-records-confirm-modal-label">
{{ 'deleted-records-item-confirm-delete-title' | i18next }}
</span>
</div>
<div class="modal-body">
{{ 'deleted-records-item-confirm-delete-message' | i18next }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
(click)="hideDestroyRecordModal()">{{ '@cancel-button' | i18next }}
</button>
<button type="button" class="btn btn-primary"
(click)="confirmDestroyRecordModal($event)">{{ 'deleted-records-item-confirm-delete-confirm' | i18next }}
</button>
</div>
</div>
</div>
</div>
</ng-container>
./deleted-records.component.scss