src/app/review/history/history.component.ts

Implements

OnInit

Metadata

Relationships

Used by

Depends on

Index

Properties
Methods
Accessors

Constructor

constructor(licenceService: LicenceService, sasStoreService: SasStoreService, eventService: EventService, router: Router, sasService: SasService)
Parameters :
Name Type Optional
licenceService LicenceService No
sasStoreService SasStoreService No
eventService EventService No
router Router No
sasService SasService No

Methods

Public download
download(id: any)
Parameters :
Name Type Optional
id any No
Returns : void
Public getApprIndex
getApprIndex(historyItem: any)
Parameters :
Name Type Optional
historyItem any No
Returns : void
Public getBaseTable
getBaseTable(baseTable: any)
Parameters :
Name Type Optional
baseTable any No
Returns : void
Public getEditTable
getEditTable(editTable: any)
Parameters :
Name Type Optional
editTable any No
Returns : void
Public getTable
getTable(table_id: any)
Parameters :
Name Type Optional
table_id any No
Returns : void
Async loadData
loadData()
Returns : any
Async ngOnInit
ngOnInit()
Returns : any

Properties

Public approveData
Type : any
Default value : {}
Public baseTableFilter
Type : unknown
Default value : new BaseTableFilter()
Public history
Type : Array<any>
Default value : []
Public historyArr
Type : Array<any>
Default value : []
Public histParams
Type : { HIST: number; STARTROW: number; NOBS: number }
Default value : { HIST: 0, STARTROW: 1, NOBS: -1 }
Public Infinity
Type : unknown
Default value : Infinity
Public itemsNum
Type : number
Default value : 10
Public licenceState
Type : unknown
Default value : this.licenceService.licenceState
Public loaded
Type : boolean
Default value : false
Public loadingMore
Type : boolean
Default value : false
Public noData
Type : boolean
Default value : false
Public openModal
Type : boolean
Default value : false
Public reviewedFilter
Type : unknown
Default value : new ReviewedFilter()
Public sasjsConfig
Type : SASjsConfig
Default value : new SASjsConfig()
Public statusFilter
Type : unknown
Default value : new StatusFilter()
Public submitReasonFilter
Type : unknown
Default value : new SubmitReasonFilter()
Public submittedFilter
Type : unknown
Default value : new SubmittedFilter()
Public submitterFilter
Type : unknown
Default value : new SubmitterFilter()
Public tableTitles
Type : Array<any>
Default value : []

Accessors

rowsLeftToLoad
getrowsLeftToLoad()
import { Component, OnInit, ViewEncapsulation } from '@angular/core'

import { Router } from '@angular/router'
import { SASjsConfig } from '@sasjs/adapter'
import {
  LicenceService,
  SasStoreService,
  EventService,
  SasService
} from 'src/app/services'
import { ClrDatagridStringFilterInterface } from '@clr/angular'

interface HistoryData {
  tableId: string
  basetable: string
  status: string
  submitter: string
  submittedReason: string
  submitted: string
  reviewed: string
}

class BaseTableFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.basetable.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

class StatusFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.status.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

class SubmitterFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.submitter.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

class SubmitReasonFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.submittedReason.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

class SubmittedFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.submitted.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

class ReviewedFilter implements ClrDatagridStringFilterInterface<HistoryData> {
  accepts(data: HistoryData, search: string): boolean {
    return data.reviewed.toLowerCase().indexOf(search.toLowerCase()) >= 0
  }
}

@Component({
  selector: 'app-history',
  templateUrl: './history.component.html',
  styleUrls: ['./history.component.scss'],
  host: {
    class: 'content-container'
  },
  encapsulation: ViewEncapsulation.None,
  standalone: false
})
export class HistoryComponent implements OnInit {
  public history: Array<any> = []
  public tableTitles: Array<any> = []
  public historyArr: Array<any> = []
  public loaded: boolean = false
  public itemsNum: number = 10
  public openModal: boolean = false
  public noData: boolean = false
  public approveData: any = {}
  public sasjsConfig: SASjsConfig = new SASjsConfig()

  // Filter instances for datagrid accessibility
  public baseTableFilter = new BaseTableFilter()
  public statusFilter = new StatusFilter()
  public submitterFilter = new SubmitterFilter()
  public submitReasonFilter = new SubmitReasonFilter()
  public submittedFilter = new SubmittedFilter()
  public reviewedFilter = new ReviewedFilter()

  public histParams: { HIST: number; STARTROW: number; NOBS: number } = {
    HIST: 0,
    STARTROW: 1,
    NOBS: -1
  }
  public loadingMore: boolean = false

  public licenceState = this.licenceService.licenceState
  public Infinity = Infinity

  constructor(
    private licenceService: LicenceService,
    private sasStoreService: SasStoreService,
    private eventService: EventService,
    private router: Router,
    private sasService: SasService
  ) {
    this.sasjsConfig = this.sasService.getSasjsConfig()
  }

  public getTable(table_id: any) {
    this.router.navigateByUrl('/stage/' + table_id)
  }

  public getBaseTable(baseTable: any) {
    this.router.navigateByUrl('/view/data/' + baseTable)
  }

  public getEditTable(editTable: any) {
    this.router.navigateByUrl('/editor/' + editTable)
  }

  public getApprIndex(historyItem: any) {
    const historyItemIndex = this.historyArr.findIndex(
      (itm: any) => itm.TABLE_ID === historyItem.tableId
    )

    if (historyItemIndex > -1) {
      this.approveData = this.historyArr[historyItemIndex]
      this.openModal = true
    }
  }

  public get rowsLeftToLoad() {
    const rowsLeft = this.histParams.NOBS - this.history.length
    const rowsInStep = this.histParams.HIST

    if (rowsLeft <= 0) return 0
    if (rowsLeft > rowsInStep) return rowsInStep

    return rowsLeft
  }

  public download(id: any) {
    let sasjsConfig = this.sasService.getSasjsConfig()
    let storage = sasjsConfig.serverUrl
    let metaData = sasjsConfig.appLoc
    let path = this.sasService.getExecutionPath()
    let downUrl =
      storage +
      path +
      '/?_program=' +
      metaData +
      '/services/auditors/getauditfile&table=' +
      id +
      '&_contextname=' +
      this.sasjsConfig.contextName
    window.open(downUrl)
  }

  async loadData() {
    let histParams = {
      STARTROW: this.histParams.HIST + this.histParams.STARTROW
    }

    this.loadingMore = true

    try {
      let res = await this.sasStoreService.getHistory(
        histParams,
        'BrowserParams',
        'approvers/gethistory'
      )

      this.loadingMore = false

      this.histParams = res.histparams[0]

      let tableTitles: Array<any>
      const fromsas = res.fromsas.slice(
        0,
        this.licenceState.value.history_rows_allowed
      )

      if (fromsas.length > 0) {
        const arr = fromsas
        this.historyArr = fromsas

        tableTitles = Object.keys(arr[0])

        this.tableTitles = tableTitles

        let historyTable = fromsas.map(function (item: any) {
          return {
            tableId: item.TABLE_ID,
            submitter: item.SUBMITTER,
            submittedReason: item.SUBMITTED_REASON_TXT,
            submitted: item.SUBMITTED,
            status: item.STATUS,
            reviewReason: item.REVIEW_REASON_TXT,
            reviewer: item.REVIEWER,
            reviewed: item.REVIEWED,
            numOfApprovals: item.NUM_OF_APPROVALS_REQUIRED,
            basetable: item.BASE_TABLE
          }
        })

        this.history.push(...historyTable)
        this.loaded = true
      } else {
        this.loaded = true

        if (this.history.length === 0) this.noData = true
      }
    } catch (error) {
      this.eventService.catchResponseError('approvers/gethistory', error)
      this.loadingMore = false
    }
  }

  async ngOnInit() {
    this.loadData()
  }
}
<div class="content-area">
  @if (noData) {
    <div
      id="noDataContainer"
      class="card-block d-flex justify-content-center flex-column align-items-center"
    >
      <clr-icon shape="warning-standard" size="60" class="is-info"></clr-icon>
      <h3 class="text-center color-gray">There is no history to show</h3>
    </div>
  }
  <clr-modal [(clrModalOpen)]="openModal" [clrModalSize]="'xl'">
    <h4 class="modal-title">Approval details</h4>
    <div class="modal-body">
      <table class="table">
        <thead>
          <tr>
            <th class="left">Name</th>
            <th class="left">Value</th>
          </tr>
        </thead>
        <tbody>
          @for (col of tableTitles; track col; let ind = $index) {
            <tr>
              <td class="left">{{ col }}</td>
              <td class="left">
                @if (ind < 1) {
                  <a
                    (click)="getTable(approveData[col])"
                    class="cursor-pointer table-link"
                    >{{ approveData[col] }}</a
                  >
                }
                @if (ind < 2 && ind >= 1) {
                  <div>
                    <a
                      (click)="getBaseTable(approveData[col])"
                      class="cursor-pointer table-link"
                      >VIEW</a
                    >
                    <span> / </span>
                    <a
                      (click)="getEditTable(approveData[col])"
                      class="cursor-pointer table-link"
                      >EDIT</a
                    >
                  </div>
                }
                @if (ind >= 2) {
                  <span>{{ approveData[col] }}</span>
                }
              </td>
            </tr>
          }
        </tbody>
      </table>
    </div>
    <div class="modal-footer">
      <button
        type="button"
        aria-label="Close modal"
        class="btn btn-outline"
        (click)="openModal = false"
      >
        OK
      </button>
    </div>
  </clr-modal>

  @if (!loaded) {
    <div
      class="h-70vh d-flex justify-content-center flex-column align-items-center"
    >
      @if (!loaded) {
        <span class="spinner"> Loading... </span>
      }
      @if (!loaded) {
        <div>
          <h3>Loading history</h3>
        </div>
      }
    </div>
  }

  @if (!noData && loaded) {
    <div class="card">
      <div class="card-header">
        @if (loaded) {
          <h3 class="center clr-col-md-12 text-center">HISTORY</h3>
        }
        @if (licenceState.value.history_rows_allowed !== Infinity) {
          <p class="text-center font-weight-700 color-dark-gray">
            To unlock more than
            {{ licenceState.value.history_rows_allowed }} records, contact
            support&#64;datacontroller.io
          </p>
        }
      </div>
      @if (loaded) {
        <clr-datagrid class="datagrid-history datagrid-custom-footer">
          <clr-dg-column [clrDgField]="'basetable'">
            BASE_TABLE
            <clr-dg-string-filter
              [clrDgStringFilter]="baseTableFilter"
              aria-label="Filter base table"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column [clrDgField]="'status'">
            STATUS
            <clr-dg-string-filter
              [clrDgStringFilter]="statusFilter"
              aria-label="Filter status"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column [clrDgField]="'submitter'">
            SUBMITTER
            <clr-dg-string-filter
              [clrDgStringFilter]="submitterFilter"
              aria-label="Filter submitter"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column [clrDgField]="'submittedReason'">
            SUBMIT REASON
            <clr-dg-string-filter
              [clrDgStringFilter]="submitReasonFilter"
              aria-label="Filter submit reason"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column [clrDgField]="'submitted'">
            SUBMITTED
            <clr-dg-string-filter
              [clrDgStringFilter]="submittedFilter"
              aria-label="Filter submitted date"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column [clrDgField]="'reviewed'">
            APPROVED / REJECTED
            <clr-dg-string-filter
              [clrDgStringFilter]="reviewedFilter"
              aria-label="Filter reviewed date"
            ></clr-dg-string-filter>
          </clr-dg-column>
          <clr-dg-column>DOWNLOAD</clr-dg-column>
          <clr-dg-row
            *clrDgItems="let historyItem of history"
            (click)="getApprIndex(historyItem)"
          >
            <clr-dg-cell class="verCenter">
              <a
                class="btn btn-sm btn-link m-0"
                (click)="getBaseTable(historyItem.basetable)"
                >{{ historyItem.basetable }}</a
              >
            </clr-dg-cell>
            <clr-dg-cell
              class="verCenter"
              [ngClass]="{
                rejected: historyItem.status === 'REJECTED',
                accepted: historyItem.status === 'APPROVED'
              }"
              >{{ historyItem.status }}</clr-dg-cell
            >
            <clr-dg-cell class="verCenter">{{
              historyItem.submitter
            }}</clr-dg-cell>
            <clr-dg-cell class="verCenter">{{
              historyItem.submittedReason
            }}</clr-dg-cell>
            <clr-dg-cell class="verCenter">{{
              historyItem.submitted
            }}</clr-dg-cell>
            <clr-dg-cell class="verCenter">{{
              historyItem.reviewed
            }}</clr-dg-cell>
            <clr-dg-cell class="verCenter p-0 d-flex justify-content-center">
              <button
                aria-label="Download audit file"
                class="btn btn-success"
                (click)="
                  download(historyItem.tableId); $event.stopPropagation()
                "
              >
                <clr-icon shape="download"></clr-icon>
              </button>
            </clr-dg-cell>
          </clr-dg-row>
          <!-- Let's keep this part if in future we decide to do the paging instead of `load more` approach -->
          <!-- <clr-dg-footer class="d-flex justify-content-start">
                    <span>items per page</span>
                    <select class="mx-5" [(ngModel)]="itemsNum">
                      <option [ngValue]="3">3</option>
                      <option [ngValue]="5">5</option>
                      <option [ngValue]="10">10</option>
                      <option [ngValue]="15">15</option>
                    </select>
                    <clr-dg-pagination
                      #pagination
                      [clrDgPageSize]="itemsNum"
                      class="center"
                      >
                      {{ pagination.firstItem + 1 }} - {{ pagination.lastItem + 1 }} of
                      {{ pagination.totalItems }} updates
                    </clr-dg-pagination>
                  </clr-dg-footer> -->
        </clr-datagrid>
      }
      <div
        class="load-more d-flex clr-justify-content-center clr-align-items-center"
      >
        @if (
          this.licenceState.value.history_rows_allowed === Infinity &&
          rowsLeftToLoad > 0
        ) {
          <button
            (click)="loadData()"
            [clrLoading]="loadingMore"
            class="btn btn-success"
          >
            Load {{ rowsLeftToLoad }} more
          </button>
        }
      </div>
    </div>
  }
</div>

./history.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""