File

angular/projects/researchdatabox/deleted-records/src/app/deleted-records.component.ts

Description

Restore deleted records Component

Extends

BaseComponent

Implements

RecordSource

Metadata

Index

Properties
Methods

Constructor

constructor(loggerService: LoggerService, recordService: RecordService, configService: ConfigService, translationService: TranslationService, elementRef: ElementRef)
Parameters :
Name Type Optional
loggerService LoggerService No
recordService RecordService No
configService ConfigService No
translationService TranslationService No
elementRef ElementRef No

Methods

Public Async confirmDestroyRecordModal
confirmDestroyRecordModal(event: any)
Parameters :
Name Type Optional
event any No
Returns : any
Public Async filter
filter(event?: any)

Apply the filters.

Parameters :
Name Type Optional Description
event any Yes

The click event data.

Returns : any
Private getConfigProp
getConfigProp(name: string, defaultValue: any)
Parameters :
Name Type Optional
name string No
defaultValue any No
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 :
Name Type Optional Description
pageNum number No

Load the data for this page nnumber.

Returns : Promise<RecordPageDto>
Public Async headerSortChanged
headerSortChanged(event: any, data: any)
Parameters :
Name Type Optional
event any No
data any No
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)
Parameters :
Name Type Optional
event any No
data any No
actionName string No
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>

Properties

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 : {}
filters
Type : ReportFilterDto[]
Default value : [ { paramName: "title", type: "text", message: "Filter by title", property: "title", }, { paramName: "recordType", type: 'drop-down', message: "Filter by record type", property: '', }, ]
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
tableHeaders
Type : RecordPropViewMetaDto[]
Default value : [ { 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 }, ]
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

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""