File

angular/projects/researchdatabox/dashboard/src/app/dashboard.component.ts

Extends

BaseComponent

Metadata

Index

Properties
Methods

Constructor

constructor(loggerService: LoggerService, utilService: UtilityService, translationService: TranslationService, recordService: RecordService, userService: UserService, configService: ConfigService, lodashTemplateUtilityService: LoDashTemplateUtilityService, elementRef: ElementRef)
Parameters :
Name Type Optional
loggerService LoggerService No
utilService UtilityService No
translationService TranslationService No
recordService RecordService No
userService UserService No
configService ConfigService No
lodashTemplateUtilityService LoDashTemplateUtilityService No
elementRef ElementRef No

Methods

Public evaluateGroupRowRules
evaluateGroupRowRules(groupRulesConfig: any, groupedItems: any, ruleSetName: string)
Parameters :
Name Type Optional
groupRulesConfig any No
groupedItems any No
ruleSetName string No
Returns : any
Public evaluatePlanTableColumns
evaluatePlanTableColumns(groupRowConfig: any, groupRowRules: any, rowLevelRulesConfig: any, stepName: string, stagedOrGroupedRecords: any)
Parameters :
Name Type Optional
groupRowConfig any No
groupRowRules any No
rowLevelRulesConfig any No
stepName string No
stagedOrGroupedRecords any No
Returns : PlanTable
Public evaluateRowLevelRules
evaluateRowLevelRules(rulesConfig: any, metadata: any, metaMetadata: any, workflow: any, oid: string, ruleSetName: string)
Parameters :
Name Type Optional
rulesConfig any No
metadata any No
metaMetadata any No
workflow any No
oid string No
ruleSetName string No
Returns : any
Public Async filterChanged
filterChanged(step: string)
Parameters :
Name Type Optional
step string No
Returns : any
Private findFilterTemplate
findFilterTemplate(filterFieldPath: string)
Parameters :
Name Type Optional
filterFieldPath string No
Returns : string
Private Async getAllItemsGroupedByRecordType
getAllItemsGroupedByRecordType(sortGroupBy: SortGroupBy[], stepName: string, startIndex: number, packageType: string, sortByString: string, filterFields: any, filterString: any, filterMode: any)
Parameters :
Name Type Optional
sortGroupBy SortGroupBy[] No
stepName string No
startIndex number No
packageType string No
sortByString string No
filterFields any No
filterString any No
filterMode any No
Returns : unknown
Private Async getAllItemsGroupedByRelationships
getAllItemsGroupedByRelationships(items: any, sortGroupBy: SortGroupBy[])
Parameters :
Name Type Optional
items any No
sortGroupBy SortGroupBy[] No
Returns : unknown
Private getFilters
getFilters(type: string)
Parameters :
Name Type Optional
type string No
Returns : {}
Public getFilterSearchDisplayed
getFilterSearchDisplayed(step: any)
Parameters :
Name Type Optional
step any No
Returns : boolean
Public getFilterSearchString
getFilterSearchString(step: any)
Parameters :
Name Type Optional
step any No
Returns : string
Private getFirstFilter
getFirstFilter(type: string)
Parameters :
Name Type Optional
type string No
Returns : FilterField
Private getFirstTextFilter
getFirstTextFilter()
Returns : FilterField
Public getIsSearching
getIsSearching(step: any)
Parameters :
Name Type Optional
step any No
Returns : boolean
Public getSecondarySortStateFromSortMap
getSecondarySortStateFromSortMap(sortMap: any, workflowStep: any, rowConfig: any)
Parameters :
Name Type Optional
sortMap any No
workflowStep any No
rowConfig any No
Returns : string
Private getSecondarySortStringFromSortMap
getSecondarySortStringFromSortMap(sortMapAtStep: any)
Parameters :
Name Type Optional
sortMapAtStep any No
Returns : string
Public getSortStateFromSortMap
getSortStateFromSortMap(sortMap: any, workflowStep: any, rowConfig: any)
Parameters :
Name Type Optional
sortMap any No
workflowStep any No
rowConfig any No
Returns : string
Private getSortStringFromSortMap
getSortStringFromSortMap(sortMapAtStep: any, forceDefault: boolean)
Parameters :
Name Type Optional Default value
sortMapAtStep any No
forceDefault boolean No false
Returns : string
Public getTextFilters
getTextFilters()
Returns : {}
Protected Async initComponent
initComponent()
Inherited from BaseComponent
Defined in BaseComponent:165
Returns : Promise<void>
Private initSortMap
initSortMap(step: any)
Parameters :
Name Type Optional
step any No
Returns : void
Public Async initStep
initStep(stepName: string, evaluateStepName: string, recordType: string, packageType: string, startIndex: number)
Parameters :
Name Type Optional
stepName string No
evaluateStepName string No
recordType string No
packageType string No
startIndex number No
Returns : any
Private initStepTableConfig
initStepTableConfig(recordType: string, step: any)
Parameters :
Name Type Optional
recordType string No
step any No
Returns : void
Public Async initView
initView(recordType: string)
Parameters :
Name Type Optional
recordType string No
Returns : any
Private Async initWorkflowSteps
initWorkflowSteps(recordType: string)
Parameters :
Name Type Optional
recordType string No
Returns : unknown
Public Async pageChanged
pageChanged(event: PageChangedEvent, step: string)
Parameters :
Name Type Optional
event PageChangedEvent No
step string No
Returns : any
Public Async resetFilterAndSearch
resetFilterAndSearch(step: string, e: any)
Parameters :
Name Type Optional
step string No
e any No
Returns : any
Private runTemplate
runTemplate(templateString: string, imports: object)
Parameters :
Name Type Optional
templateString string No
imports object No
Returns : any
Public setFilterField
setFilterField(filterField: FilterField, e: any)
Parameters :
Name Type Optional
filterField FilterField No
e any No
Returns : void
Public Async sortChanged
sortChanged(data: any)
Parameters :
Name Type Optional
data any No
Returns : any
Private updateSortMap
updateSortMap(sortData: any)
Parameters :
Name Type Optional
sortData any No
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

baseUrl
Type : string
Default value : ''
branding
Type : string
Default value : ''
config
Type : any
Default value : {}
currentUser
Type : object
Default value : {}
dashboardColumnMappings
Type : any
Default value : { dateCreated: 'dateCreated', dateModified: 'dateModified', dashboardTitle: 'dashboardTitle', oid: 'oid', title: 'title', metadata: 'metadata.metadata', metaMetadata: 'metadata.metaMetadata', packageType: 'metadata.packageType', workflow: 'metadata.workflow', hasEditAccess: 'hasEditAccess', recordType: 'metadata.metaMetadata.type' }
dashboardTypeOptions
Type : any
Default value : ['standard', 'workspace', 'consolidated']
dashboardTypeSelected
Type : string
defaultDashboardTypeSelected
Type : string
Default value : this.dashboardTypeOptions[0]
defaultFilterField
Type : FilterField
Default value : { name: this.filterFieldName, path: this.filterFieldPath }
defaultFormatRules
Type : FormatRules
Default value : { filterBy: {}, //filterBase can only have two values user or record filterWorkflowStepsBy: [], //values: empty array (all) or a list with particular types i.e. [ 'draft', 'finalised' ] recordTypeFilterBy: '', queryFilters: { rdmp: [ { filterType: 'text', filterFields: [ { name: 'Title', path: 'metadata.title' } ] } ] }, sortBy: 'metaMetadata.lastSaveDate:-1', groupBy: '', //values: empty (not grouped any order), groupedByRecordType, groupedByRelationships sortGroupBy: [], //values: as many levels as required? hideWorkflowStepTitleForRecordType: [] }
defaultGroupRowConfig
Type : object
Default value : {}
defaultGroupRowRules
Type : any
Default value : {}
defaultRowConfig
Type : []
Default value : [ { title: 'Record Title', variable: 'metadata.title', template: `<a href='<%=rootContext%>/<%= branding %>/<%= portal %>/record/view/<%= oid %>'><%= metadata.title %></a> <span class="dashboard-controls"> <% if(hasEditAccess) { %> <a href='<%=rootContext%>/<%= branding %>/<%= portal %>/record/edit/<%= oid %>' aria-label='<%= translationService.t('edit-link-label') %>'><i class="fa fa-pencil" aria-hidden="true"></i></a> <% } %> </span> `, initialSort: 'desc' }, { title: 'header-ci', variable: 'metadata.contributor_ci.text_full_name', template: '<%= metadata.contributor_ci != undefined ? metadata.contributor_ci.text_full_name : "" %>', initialSort: 'desc' }, { title: 'header-data-manager', variable: 'metadata.contributor_data_manager.text_full_name', template: '<%= metadata.contributor_data_manager != undefined ? metadata.contributor_data_manager.text_full_name : "" %>', initialSort: 'desc' }, { title: 'header-created', variable: 'metaMetadata.createdOn', template: '<%= util.formatDateLocale(util.parseDateString(dateCreated), "DATETIME_MED") %>', initialSort: 'desc' }, { title: 'header-modified', variable: 'metaMetadata.lastSaveDate', template: '<%= util.formatDateLocale(util.parseDateString(dateModified),"DATETIME_MED") %>', initialSort: 'desc', defaultSort: true } ]
defaultRowLevelRules
Type : any
Default value : {}
defaultSortObject
Type : any
Default value : {}
enableSort
Type : boolean
Default value : true
filterFieldName
Type : string
Default value : 'Title'
filterFieldPath
Type : string
Default value : 'metadata.title'
filterSearchString
Type : any
Default value : {}
formatRules
Type : FormatRules
Default value : this.defaultFormatRules
groupRowConfig
Type : object
Default value : {}
groupRowRules
Type : any
Default value : {}
hideWorkflowStepTitle
Type : boolean
Default value : false
isFilterSearchDisplayed
Type : any
Default value : {}
isProcessingPageChange
Type : boolean
Default value : false
isSearching
Type : any
Default value : {}
packageType
Type : string
portal
Type : string
Default value : ''
records
Type : any
Default value : {}
recordType
Type : string
rootContext
Type : string
Default value : ''
rowLevelRules
Type : any
Default value : {}
rulesService
Type : object
sortFields
Type : []
Default value : ['metaMetadata.lastSaveDate', 'metaMetadata.createdOn', 'metadata.title', 'metadata.contributor_ci.text_full_name', 'metadata.contributor_data_manager.text_full_name']
sortMap
Type : any
Default value : {}
tableConfig
Type : any
Default value : {}
typeLabel
Type : string
Default value : ''
workflowSteps
Type : any
Default value : []
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 } from '@angular/core';
import { PageChangedEvent } from 'ngx-bootstrap/pagination';
import { BaseComponent, UtilityService, LoggerService, TranslationService, RecordService, PlanTable, UserService, ConfigService, FormatRules, SortGroupBy, QueryFilter, FilterField } from '@researchdatabox/portal-ng-common';
import { get as _get, set as _set, isEmpty as _isEmpty, isUndefined as _isUndefined, trim as _trim, isNull as _isNull, orderBy as _orderBy, map as _map, find as _find, indexOf as _indexOf, isArray as _isArray, forEach as _forEach, join as _join, first as _first, has as _has } from 'lodash-es';
import { LoDashTemplateUtilityService } from 'projects/researchdatabox/portal-ng-common/src/lib/lodash-template-utility.service';

@Component({
  selector: 'dashboard',
  templateUrl: './dashboard.component.html'
})
export class DashboardComponent extends BaseComponent {
  config: any = {};
  branding: string = '';
  portal: string = '';
  rootContext: string = '';
  baseUrl: string = '';
  workflowSteps: any = [];
  typeLabel: string = '';
  recordType: string;
  packageType: string;
  records: any = {};
  sortMap: any = {};
  tableConfig: any = {};
  dashboardTypeOptions: any = ['standard', 'workspace', 'consolidated'];
  defaultDashboardTypeSelected: string = this.dashboardTypeOptions[0];
  dashboardTypeSelected: string;
  rulesService: object;
  currentUser: object = {};
  enableSort: boolean = true;
  filterFieldName: string = 'Title';
  filterFieldPath: string = 'metadata.title';
  defaultFilterField: FilterField = { name: this.filterFieldName, path: this.filterFieldPath };
  filterSearchString: any = {};
  hideWorkflowStepTitle: boolean = false;
  isFilterSearchDisplayed: any = {};
  isSearching: any = {};
  isProcessingPageChange: boolean = false;
  defaultSortObject: any = {};

  defaultRowConfig = [
    {
      title: 'Record Title',
      variable: 'metadata.title',
      template: `<a href='<%=rootContext%>/<%= branding %>/<%= portal %>/record/view/<%= oid %>'><%= metadata.title %></a>
          <span class="dashboard-controls">
            <% if(hasEditAccess) { %>
              <a href='<%=rootContext%>/<%= branding %>/<%= portal %>/record/edit/<%= oid %>' aria-label='<%= translationService.t('edit-link-label') %>'><i class="fa fa-pencil" aria-hidden="true"></i></a>
            <% } %>
          </span>
        `,
      initialSort: 'desc'
    },
    {
      title: 'header-ci',
      variable: 'metadata.contributor_ci.text_full_name',
      template: '<%= metadata.contributor_ci != undefined ? metadata.contributor_ci.text_full_name : "" %>',
      initialSort: 'desc'
    },
    {
      title: 'header-data-manager',
      variable: 'metadata.contributor_data_manager.text_full_name',
      template: '<%= metadata.contributor_data_manager != undefined ? metadata.contributor_data_manager.text_full_name : "" %>',
      initialSort: 'desc'
    },
    {
      title: 'header-created',
      variable: 'metaMetadata.createdOn',
      template: '<%= util.formatDateLocale(util.parseDateString(dateCreated), "DATETIME_MED") %>',
      initialSort: 'desc'
    },
    {
      title: 'header-modified',
      variable: 'metaMetadata.lastSaveDate',
      template: '<%= util.formatDateLocale(util.parseDateString(dateModified),"DATETIME_MED") %>',
      initialSort: 'desc',
      defaultSort: true
    }
  ];

  dashboardColumnMappings: any = {
    dateCreated: 'dateCreated',
    dateModified: 'dateModified',
    dashboardTitle: 'dashboardTitle',
    oid: 'oid',
    title: 'title',
    metadata: 'metadata.metadata',
    metaMetadata: 'metadata.metaMetadata',
    packageType: 'metadata.packageType',
    workflow: 'metadata.workflow',
    hasEditAccess: 'hasEditAccess',
    recordType: 'metadata.metaMetadata.type'
  };

  //Format rule types :
  // filter(record types, field values, workflow steps) and sortBy(simple) or groupBy(relationships hierarchy ) 

  //Format rule modes:
  // per grouped records or table wide

  sortFields = ['metaMetadata.lastSaveDate', 'metaMetadata.createdOn', 'metadata.title', 'metadata.contributor_ci.text_full_name', 'metadata.contributor_data_manager.text_full_name'];

  defaultFormatRules: FormatRules = {
    filterBy: {}, //filterBase can only have two values user or record
    filterWorkflowStepsBy: [], //values: empty array (all) or a list with particular types i.e. [ 'draft', 'finalised' ]  
    recordTypeFilterBy: '',
    queryFilters: {
      rdmp: [
              { 
                filterType: 'text',
                filterFields: [
                                { 
                                  name: 'Title',
                                  path: 'metadata.title'
                                }
                              ]
              }
            ]
      },
    sortBy: 'metaMetadata.lastSaveDate:-1',
    groupBy: '', //values: empty (not grouped any order), groupedByRecordType, groupedByRelationships 
    sortGroupBy: [], //values: as many levels as required?
    hideWorkflowStepTitleForRecordType: []
  };
  formatRules: FormatRules = this.defaultFormatRules;

  defaultGroupRowConfig = {};
  groupRowConfig = {};

  //Per group rules like show/hide buttons/activities(links) that apply to one group
  defaultGroupRowRules: any = {};
  groupRowRules: any = {};

  //Per each row rules show/hide fields or buttons/activities(links) that apply to one row
  defaultRowLevelRules: any = {};
  rowLevelRules: any = {};

  constructor(
    @Inject(LoggerService) private loggerService: LoggerService,
    @Inject(UtilityService) private utilService: UtilityService,
    @Inject(TranslationService) private translationService: TranslationService,
    @Inject(RecordService) private recordService: RecordService,
    @Inject(UserService) private userService: UserService,
    @Inject(ConfigService) private configService: ConfigService,
    @Inject(LoDashTemplateUtilityService) private lodashTemplateUtilityService: LoDashTemplateUtilityService,
    elementRef: ElementRef
  ) {
    super();
    this.recordType = _trim(elementRef.nativeElement.getAttribute('recordType'));
    this.packageType = _trim(elementRef.nativeElement.getAttribute('packageType'));
    let dashboardType = _trim(elementRef.nativeElement.getAttribute('dashboardType'));
    if (_isUndefined(dashboardType) || _isNull(dashboardType) || _isEmpty(dashboardType)) {
      this.dashboardTypeSelected = this.defaultDashboardTypeSelected;
    } else {
      this.dashboardTypeSelected = dashboardType;
    }
    if (!_isUndefined(this.packageType) && !_isNull(this.packageType) && !_isEmpty(this.packageType)) {
      this.dashboardTypeSelected = this.packageType;
    }

    this.initDependencies = [this.translationService, this.recordService, this.userService];
    console.log(`constructor dashboardTypeSelected ${this.dashboardTypeSelected} ${this.packageType}`);
    this.rulesService = this;
  }

  protected override async initComponent(): Promise<void> {
    if (_indexOf(this.dashboardTypeOptions, this.dashboardTypeSelected) >= 0) {
      this.loggerService.debug(`Dashboard waiting for deps to init...`);
      this.loggerService.debug(`Dashboard initialised.`);
      this.config = this.recordService.getConfig();
      this.baseUrl = _get(this.config, 'baseUrl');
      this.rootContext = this.configService.rootContext;
      this.branding = _get(this.config, 'branding');
      this.portal = _get(this.config, 'portal');
      this.typeLabel = `${this.translationService.t(`${this.recordType}-name-plural`)}` || 'Records';
      this.currentUser = await this.userService.getInfo();
      await this.initView(this.recordType);
    } else {
      this.loggerService.debug(`Unsupported Dashboard Type: ${this.dashboardTypeSelected}`);
    }
  }

  public async initView(recordType: string) {

    this.formatRules = this.defaultFormatRules;
    this.rowLevelRules = this.defaultRowLevelRules;
    this.groupRowConfig = this.defaultGroupRowConfig;
    this.groupRowRules = this.defaultGroupRowRules;

    let dashboardTypeConfig: any = await this.recordService.getDashboardType(this.dashboardTypeSelected);
    let formatRules: FormatRules = _get(dashboardTypeConfig, 'formatRules');
    if (!_isUndefined(formatRules) && !_isNull(formatRules) && !_isEmpty(formatRules)) {
      //global format rules from dashboardtype.js config
      this.formatRules = formatRules;
    }

    let recordTypeFilterBy = _get(this.formatRules, 'recordTypeFilterBy');
    if (!_isUndefined(recordTypeFilterBy) && !_isNull(formatRules) && !_isEmpty(formatRules)) {
      recordType = recordTypeFilterBy;
    }

    for(let recType of formatRules.hideWorkflowStepTitleForRecordType) {
      if(recType == recordType) {
        this.hideWorkflowStepTitle = true;
      }
    }

    let steps = await this.initWorkflowSteps(recordType);

    let startIndex = 1;
    for (let step of steps) {

      this.initStepTableConfig(recordType, step);

      this.initSortMap(step);

      this.workflowSteps.push(step);

      let packageType = '';
      let stepName = '';
      let evaluateStepName = '';
      if (this.dashboardTypeSelected == 'consolidated') {
        packageType = '';
        stepName = '';
        evaluateStepName = _get(step, 'name');
        recordType = _get(step, 'config.baseRecordType');
      } else if (this.dashboardTypeSelected == 'workspace') {
        stepName = '';
        packageType = this.packageType;
        evaluateStepName = _get(step, 'name');
        recordType = '';
      } else {
        packageType = '';
        stepName = _get(step, 'name');
        evaluateStepName = stepName;
      }

      await this.initStep(stepName, evaluateStepName, recordType, packageType, startIndex);
    }
  }

  private async initWorkflowSteps(recordType: string) {

    let beforeFilterSteps: any = await this.recordService.getWorkflowSteps(recordType);

    let filterWorkflowStepsBy = _get(this.formatRules, 'filterWorkflowStepsBy');
    let steps = [];

    if (!_isUndefined(filterWorkflowStepsBy) && _isArray(filterWorkflowStepsBy) && !_isEmpty(filterWorkflowStepsBy)) {
      for (let bfStep of beforeFilterSteps) {
        let filterByStage = _get(bfStep, 'config.workflow.stage');
        if (!_isUndefined(filterByStage)) {
          let indexFilterByStage = _indexOf(filterWorkflowStepsBy, filterByStage);
          if (indexFilterByStage >= 0) {
            steps.push(bfStep);
          }
        }
      }
    } else {
      steps = beforeFilterSteps;
    }
    steps = _orderBy(steps, ['config.displayIndex'], ['asc']);
    return steps;
  }

  private initStepTableConfig(recordType: string, step: any) {

    let stepRowConfig = this.defaultRowConfig;

    if (_isEmpty(this.defaultRowConfig[0].title)) {
      this.defaultRowConfig[0].title = `${recordType}-title` || 'Title';
    }

    if (!_isUndefined(_get(step, 'config.dashboard'))
      && !_isUndefined(_get(step, 'config.dashboard.table'))) {

      if (!_isUndefined(_get(step, 'config.dashboard.table.rowConfig'))) {
        stepRowConfig = _get(step, 'config.dashboard.table.rowConfig');
        this.sortFields = _map(_get(step, 'config.dashboard.table.rowConfig'), (config) => { return config.variable; });
      }

      if (!_isUndefined(_get(step, 'config.dashboard.table.rowRulesConfig'))) {
        this.rowLevelRules = _get(step, 'config.dashboard.table.rowRulesConfig');
      }

      if (!_isUndefined(_get(step, 'config.dashboard.table.groupRowConfig'))) {
        this.groupRowConfig = _get(step, 'config.dashboard.table.groupRowConfig');
      }

      if (!_isUndefined(_get(step, 'config.dashboard.table.groupRowRulesConfig'))) {
        this.groupRowRules = _get(step, 'config.dashboard.table.groupRowRulesConfig');
      }

      //formtatRules override at step level from workflow.js config
      if (!_isUndefined(_get(step, 'config.dashboard.table.formatRules'))) {
        this.formatRules = _get(step, 'config.dashboard.table.formatRules');
      }
    }

    this.tableConfig[step.name] = stepRowConfig;
  }

  public async initStep(stepName: string, evaluateStepName: string, recordType: string, packageType: string, startIndex: number) {

    let filterBy = _get(this.formatRules, 'filterBy');
    let filterString;
    let filterFields;
    let filterMode;
    if (!_isUndefined(filterBy) && !_isEmpty(filterBy)) {
      let filterBase = _get(filterBy, 'filterBase');
      if (filterBase == 'user') {
        let filterBaseObj = this.currentUser;
        filterString = _get(filterBaseObj, _get(filterBy, 'filterBaseFieldOrValue'));
      } else if (filterBase == 'record') {
        filterString = _get(filterBy, 'filterBaseFieldOrValue');
      }
      filterFields = _get(filterBy, 'filterField');
      filterMode = _get(filterBy, 'filterMode');
    }

    let sortByString = this.getSortStringFromSortMap(this.sortMap[stepName], true);

    let stagedRecords = await this.recordService.getRecords(recordType, stepName, startIndex, packageType, sortByString, filterFields, filterString, filterMode);

    let planTable: PlanTable;

    if (this.dashboardTypeSelected == 'consolidated') {
      let items: any = _get(stagedRecords, 'items');
      let totalItems = _get(stagedRecords, 'totalItems');
      let noItemsPerPage = _get(stagedRecords, 'noItems');
      let allItemsByGroup = [];

      let groupBy = _get(this.formatRules, 'groupBy');
      let sortGroupBy = _get(this.formatRules, 'sortGroupBy');

      if (groupBy == 'groupedByRelationships' && !_isUndefined(sortGroupBy) && !_isEmpty(sortGroupBy)) {

        allItemsByGroup = await this.getAllItemsGroupedByRelationships(items, sortGroupBy);

      } else if (groupBy == 'groupedByRecordType' && !_isUndefined(sortGroupBy) && !_isEmpty(sortGroupBy)) {

        allItemsByGroup = await this.getAllItemsGroupedByRecordType(sortGroupBy, stepName, startIndex, packageType, sortByString, filterFields, filterString, filterMode);
      }

      let pageNumber = _get(stagedRecords, 'currentPage');

      let groupedRecords: any = {};
      _set(groupedRecords, 'totalItems', totalItems);
      _set(groupedRecords, 'currentPage', pageNumber);
      _set(groupedRecords, 'noItems', noItemsPerPage);
      _set(groupedRecords, 'itemsByGroup', true);
      _set(groupedRecords, 'groupedItems', allItemsByGroup);

      planTable = this.evaluatePlanTableColumns(this.groupRowConfig, this.groupRowRules, this.rowLevelRules, evaluateStepName, groupedRecords);

    } else {

      planTable = this.evaluatePlanTableColumns({}, {}, {}, evaluateStepName, stagedRecords);

      if (this.dashboardTypeSelected == 'standard' || this.dashboardTypeSelected == 'workspace') {
        let filter: FilterField = this.getFirstTextFilter();
        this.filterFieldName = filter.name;
        this.filterFieldPath = filter.path;
      }
    }

    this.records[evaluateStepName] = planTable;

    this.sortChanged(this.defaultSortObject);
  }

  private async getAllItemsGroupedByRecordType(sortGroupBy: SortGroupBy[], stepName: string, startIndex: number, packageType: string, sortByString: string, filterFields: any, filterString: any, filterMode: any) {
    let allItemsByGroup: any[] = [];
    let countHerarchyLevels = sortGroupBy.length;
    for (let i = 0; i < countHerarchyLevels; i++) {

      let rule = _find(sortGroupBy, function (o) {
        if (_get(o, 'rowLevel') == i) {
          return true;
        }
        return false;
      });
      let compareFieldValue = _get(rule, 'compareFieldValue', '');
      let itemsGroupRelated: any = await this.recordService.getRecords(compareFieldValue, stepName, startIndex, packageType, sortByString, filterFields, filterString, filterMode);

      allItemsByGroup.push(itemsGroupRelated);
    }

    return allItemsByGroup;
  }

  private async getAllItemsGroupedByRelationships(items: any, sortGroupBy: SortGroupBy[]) {
    let allItemsByGroup: any[] = [];
    for (let item of items) {
      let oid = _get(item, 'oid');
      let itemsAfterApplyInnerGroupFormatRules = [];

      let itemsGroupRelated: any = await this.recordService.getRelatedRecords(oid);
      let sortItems = _get(itemsGroupRelated, 'items');
      let totalSortItems = sortItems.length;
      let countHerarchyLevels = sortGroupBy.length;

      for (let j = 0; j < totalSortItems; j++) {
        let parentTreeNodeOid = oid;
        for (let i = 0; i < countHerarchyLevels; i++) {
          let rule = _find(sortGroupBy, function (o) {
            if (_get(o, 'rowLevel') == i) {
              return true;
            }
            return false;
          });
          let compareField = _get(rule, 'compareField', '');
          let compareFieldValue = _get(rule, 'compareFieldValue', '');
          let relatedTo = _get(rule, 'relatedTo', '');

          for (let sortItem of sortItems) {
            let relatedToOid = _get(sortItem, relatedTo);
            let foundParent = relatedToOid == parentTreeNodeOid;
            let foundRecord = _get(sortItem, compareField) == compareFieldValue;
            let foundTopLevelParent = relatedTo == '';
            if (foundRecord && (foundParent || foundTopLevelParent)) {
              let currentOid = _get(sortItem, 'oid');
              let rowExists = _find(itemsAfterApplyInnerGroupFormatRules, ['oid', currentOid]);
              if (_isUndefined(rowExists)) {
                itemsAfterApplyInnerGroupFormatRules.push(sortItem);
                if ((i + 1) < countHerarchyLevels) {
                  parentTreeNodeOid = currentOid;
                  break;
                }
              }
            }
          }
        }
      }

      if (!_isEmpty(itemsAfterApplyInnerGroupFormatRules)) {
        _set(itemsGroupRelated, 'items', itemsAfterApplyInnerGroupFormatRules);
      }

      allItemsByGroup.push(itemsGroupRelated);
    }
    return allItemsByGroup;
  }

  public evaluatePlanTableColumns(groupRowConfig: any, groupRowRules: any, rowLevelRulesConfig: any, stepName: string, stagedOrGroupedRecords: any): PlanTable {

    let recordRows: any = [];
    let planTable: PlanTable = {
      items: [],
      totalItems: _get(stagedOrGroupedRecords, 'totalItems'),
      currentPage: _get(stagedOrGroupedRecords, 'currentPage'),
      noItems: _get(stagedOrGroupedRecords, 'noItems')
    };

    let columnMappings = this.dashboardColumnMappings;

    let isGrouped = _get(stagedOrGroupedRecords, 'itemsByGroup');
    let allGroupedItems = _get(stagedOrGroupedRecords, 'groupedItems');
    if (isGrouped && !_isUndefined(allGroupedItems) && !_isEmpty(allGroupedItems)) {

      const imports: any = {};
      for (let groupedRecords of allGroupedItems) {

        let groupedItems = _get(groupedRecords, 'items');

        for (let stagedRecord of groupedItems) {

          _forEach(columnMappings, (value, key) => {
            _set(imports, key, _get(stagedRecord, value));
          });

          _set(imports, 'branding', this.branding);
          _set(imports, 'rootContext', this.rootContext);
          _set(imports, 'baseUrl', this.baseUrl);
          _set(imports, 'portal', this.portal);
          _set(imports, 'translationService', this.translationService);
          _set(imports, 'rulesService', this.rulesService);
          _set(imports, 'rulesConfig', rowLevelRulesConfig);
          if (!_isUndefined(groupRowRules) && !_isEmpty(groupRowRules)) {
            _set(imports, 'groupRulesConfig', groupRowRules);
            _set(imports, 'groupedItems', groupedItems);
          }

          let record: any = {};

          let stepRowConfig: any[] = this.tableConfig[stepName];

          for (let columnConfig of stepRowConfig) {
            const templateRes = this.runTemplate(columnConfig.template, imports)
            record[columnConfig.variable] = templateRes;
          }
          recordRows.push(record);
        }

        //Don't evaluate group rules if no records were retrieved meaning recordsRows array has length 0
        if (!_isUndefined(groupRowConfig) && !_isEmpty(groupRowConfig) && recordRows.length > 0 && !_isEmpty(imports)) {

          let groupRecord: any = {};
          for (let groupRow of groupRowConfig) {

            const groupTemplateRes = this.runTemplate(groupRow.template, imports);
            groupRecord[groupRow.variable] = groupTemplateRes;
          }
          recordRows.push(groupRecord);
        }
      }

    } else {

      let stagedOrGroupedRecordItems = _get(stagedOrGroupedRecords, 'items');
      if (!_isUndefined(stagedOrGroupedRecordItems) && !_isEmpty(stagedOrGroupedRecordItems)) {

        for (let stagedRecord of stagedOrGroupedRecordItems) {

          const imports: any = {};

          _forEach(columnMappings, (value, key) => {
            _set(imports, key, _get(stagedRecord, value));
          });

          _set(imports, 'branding', this.branding);
          _set(imports, 'rootContext', this.rootContext);
          _set(imports, 'portal', this.portal);
          _set(imports, 'translationService', this.translationService);

          let record: any = {};
          let stepRowConfig = this.tableConfig[stepName];

          for (let columnConfig of stepRowConfig) {
            const templateRes = this.runTemplate(columnConfig.template, imports);
            record[columnConfig.variable] = templateRes;
          }
          recordRows.push(record);
        }
      }
    }

    planTable.items = recordRows;

    return planTable;
  }

  public evaluateRowLevelRules(rulesConfig: any, metadata: any, metaMetadata: any, workflow: any, oid: string, ruleSetName: string) {

    let res: any;
    const imports: any = {};
    _set(imports, 'metadata', metadata);
    _set(imports, 'metaMetadata', metaMetadata);
    _set(imports, 'workflow', workflow);
    _set(imports, 'oid', oid);
    _set(imports, 'branding', this.branding);
    _set(imports, 'rootContext', this.rootContext);
    _set(imports, 'portal', this.portal);
    _set(imports, 'translationService', this.translationService);

    let ruleSetConfig = _find(rulesConfig, ['ruleSetName', ruleSetName]);

    if (!_isUndefined(ruleSetConfig)) {

      if (_get(ruleSetConfig, 'applyRuleSet') == true) {

        let rules = _get(ruleSetConfig, 'rules');
        let resArray = [];

        for (let rule of rules) {
          let name = _get(rule, 'name');
          console.log('evaluating rule ' + name);
          let renderItemTemplate = _get(rule, 'renderItemTemplate');
          let evaluateRulesTemplate = _get(rule, 'evaluateRulesTemplate');
          _set(imports, 'name', name);

          let evaluatedAction = '';
          let action = _get(rule, 'action');

          const result = this.runTemplate(evaluateRulesTemplate, imports)
          if (result == 'true') {
            evaluatedAction = action;
          }

          if (evaluatedAction == 'show') {
            const templateRes = this.runTemplate(renderItemTemplate, imports);
            resArray.push(templateRes);
          }
        }

        if (_get(ruleSetConfig, 'type') == 'multi-item-rendering') {
          let separator = _get(ruleSetConfig, 'separator');
          res = _join(resArray, separator);
        } else {
          res = _first(resArray);
        }
      }
    }

    return res;
  }

  public evaluateGroupRowRules(groupRulesConfig: any, groupedItems: any, ruleSetName: string) {

    let res: any;

    let ruleSetConfig = _find(groupRulesConfig, ['ruleSetName', ruleSetName]);

    if (!_isUndefined(ruleSetConfig)) {

      if (_get(ruleSetConfig, 'applyRuleSet') == true) {

        let rules = _get(ruleSetConfig, 'rules');
        let resArray = [];

        for (let rule of rules) {

          let name = _get(rule, 'name');
          console.log('evaluating rule ' + name);
          let renderItemTemplate = _get(rule, 'renderItemTemplate');
          let evaluateRulesTemplate = _get(rule, 'evaluateRulesTemplate');
          let evaluatedAction = '';
          let results = [];
          let action = _get(rule, 'action');
          let mode = _get(rule, 'mode');

          const imports: any = {};
          for (let item of groupedItems) {

            _set(imports, 'metadata', _get(item, 'metadata.metadata'));
            _set(imports, 'metaMetadata', _get(item, 'metadata.metaMetadata'));
            _set(imports, 'workflow', _get(item, 'metadata.workflow'));
            _set(imports, 'branding', this.branding);
            _set(imports, 'rootContext', this.rootContext);
            _set(imports, 'portal', this.portal);
            _set(imports, 'translationService', this.translationService);

            let oid = _get(item, 'oid');
            _set(imports, 'oid', oid);
            _set(imports, 'name', name);

            const result = this.runTemplate(evaluateRulesTemplate, imports);
            if (result == 'true') {
              results.push(result);
            } else if (mode == 'all') {
              results.push(result);
            }
          }

          if (!_isEmpty(results) && (_indexOf(results, 'false') < 0) && (_indexOf(results, 'true') >= 0)) {
            evaluatedAction = action;
          }


          if (evaluatedAction == 'show') {
            const templateRes = this.runTemplate(renderItemTemplate, imports);
            resArray.push(templateRes);
          }
        }

        if (_get(ruleSetConfig, 'type') == 'multi-item-rendering') {
          let separator = _get(ruleSetConfig, 'separator');
          res = _join(resArray, separator);
        } else {
          res = _first(resArray);
        }
      }
    }

    return res;
  }

  private initSortMap(step: any) {

    let stepRowConfig: any[] = this.tableConfig[step.name];

    this.sortMap[step.name] = {};

    let stepRowConfigLength = stepRowConfig.length - 1;

    let i = 0;

    for (let columnConfig of stepRowConfig) {

      i = i + 1;

      if(columnConfig.initialSort == 'asc' || columnConfig.initialSort == 'desc') {

        this.sortMap[step.name][columnConfig.variable] = {
          sort: columnConfig.initialSort,
          secondarySort: columnConfig.secondarySort != undefined ? columnConfig.secondarySort : '',
          defaultSort:  columnConfig.defaultSort == true ? true : false
        }
      }

      if(columnConfig.defaultSort == true) {
        this.defaultSortObject = {
          sort: columnConfig.initialSort,
          secondarySort: columnConfig.secondarySort != undefined ? columnConfig.secondarySort : '',
          step: step.name,
          title: '',
          variable: columnConfig.variable
        }
      } else if(i == stepRowConfigLength && _isEmpty(this.defaultSortObject)) {
        this.defaultSortObject = {
          sort: columnConfig.initialSort,
          secondarySort: columnConfig.secondarySort != undefined ? columnConfig.secondarySort : '',
          step: step.name,
          title: '',
          variable: columnConfig.variable
        }
      }
    }

    if (this.dashboardTypeSelected == 'consolidated') {
      this.enableSort = false;
    } else {
      this.enableSort = true;
    }
  }

  public async sortChanged(data: any) {

    if (this.dashboardTypeSelected == 'standard' || this.dashboardTypeSelected == 'workspace') {
      
      let sortString = `${data.variable}:`;
      let secondarySortString = undefined;
      if (data.sort == 'desc') {
        sortString = sortString + "-1";
        if(data.secondarySort != undefined && data.secondarySort != '') {
          secondarySortString = `${data.secondarySort}:`+ "-1";
        }
      } else {
        sortString = sortString + "1";
        if(data.secondarySort != undefined && data.secondarySort != '') {
          secondarySortString = `${data.secondarySort}:`+ "1";
        }
      }
      let stagedRecords: any;
      if (this.dashboardTypeSelected == 'workspace') {
        stagedRecords = await this.recordService.getRecords('', '', 1, this.dashboardTypeSelected, sortString,this.filterFieldPath,this.getFilterSearchString(data.step),'',secondarySortString);
      } else {
        stagedRecords = await this.recordService.getRecords(this.recordType, data.step, 1, '', sortString,this.filterFieldPath,this.getFilterSearchString(data.step),'',secondarySortString);
      }

      let planTable: PlanTable = this.evaluatePlanTableColumns({}, {}, {}, data.step, stagedRecords);

      this.records[data.step] = planTable;

      this.updateSortMap(data);
    }
  }

  private updateSortMap(sortData: any) {

    let stepRowConfig: any[] = this.tableConfig[sortData.step];
    for (let columnConfig of stepRowConfig) {
      this.sortMap[sortData.step][columnConfig.variable] = { 
        sort: columnConfig.noSort ,
        secondarySort: columnConfig.secondarySort != '' ? columnConfig.secondarySort : ''
      };
    }

    this.sortMap[sortData.step][sortData.variable] = { 
      sort: sortData.sort,
      secondarySort: sortData.secondarySort
     };
  }

  public async pageChanged(event: PageChangedEvent, step: string) {
    
    if (this.isProcessingPageChange) {
      return;
    }

    this.isProcessingPageChange = true;

    let sortMapAtStep = this.sortMap[step];

    if (this.dashboardTypeSelected == 'standard') {
      let stagedRecords = await this.recordService.getRecords(this.recordType, step, event.page, '', this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      let planTable: PlanTable = this.evaluatePlanTableColumns({}, {}, {}, step, stagedRecords);
      this.records[step] = planTable;
      this.isProcessingPageChange = false;
    } else if (this.dashboardTypeSelected == 'workspace') {
      let stagedRecords = await this.recordService.getRecords('', '', event.page, this.packageType, this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      let planTable: PlanTable = this.evaluatePlanTableColumns({}, {}, {}, step, stagedRecords);
      this.records[step] = planTable;
      this.isProcessingPageChange = false;
    } else if (this.dashboardTypeSelected == 'consolidated') {
      let packageType = '';
      let stepName = '';
      let evaluateStepName = _get(this.workflowSteps[0], 'name');
      let recordType = _get(this.workflowSteps[0], 'config.baseRecordType');
      await this.initStep(stepName, evaluateStepName, recordType, packageType, event.page);
      this.isProcessingPageChange = false;
    }
  }

  private runTemplate(templateString: string, imports: object): any {
    let config: any = {
      template: templateString
    }
    let data = {}
    return this.lodashTemplateUtilityService.runTemplate(data, config, imports)
  }

  public getSortStateFromSortMap(sortMap: any, workflowStep: any, rowConfig: any) {
    let step = _get(workflowStep,'config.workflow.stage','');
    let sort = 'desc';
    if(step != '') {
      let sortMapAtStep = sortMap[step];
      if(_has(sortMapAtStep,rowConfig.variable)) {
        sort = sortMapAtStep[rowConfig.variable].sort;
        return sort;
      }
    }
    return sort;
  }

  public getSecondarySortStateFromSortMap(sortMap: any, workflowStep: any, rowConfig: any) {
    let step = _get(workflowStep,'config.workflow.stage','');
    let secondarySort = 'desc';
    if(step != '') {
      let sortMapAtStep = sortMap[step];
      if(_has(sortMapAtStep,rowConfig.variable)) {
        secondarySort = sortMapAtStep[rowConfig.variable].secondarySort;
        return secondarySort;
      }
    }
    return secondarySort;
  }


  private getSortStringFromSortMap(sortMapAtStep: any, forceDefault: boolean = false) {

    let fields = this.sortFields;
    let sortString = 'metaMetadata.lastSaveDate:-1';
    for (let i = 0; i < fields.length; i++) {
      let sortField = fields[i];
      if(!_isEmpty(sortMapAtStep) && !_isEmpty(sortField) && _has(sortMapAtStep,sortField)) {
        if (sortMapAtStep[sortField].sort != null && forceDefault && sortMapAtStep[sortField].defaultSort == true) {
          sortString = `${sortField}:`;
          if (sortMapAtStep[sortField].sort == 'desc') {
            sortString = sortString + "-1";
          } else {
            sortString = sortString + "1";
          }
          return sortString;
        } else {
          if (sortMapAtStep[sortField].sort != null) {
            sortString = `${sortField}:`;
            if (sortMapAtStep[sortField].sort == 'desc') {
              sortString = sortString + "-1";
            } else {
              sortString = sortString + "1";
            }
          }
        } 
      }
    }
    return sortString;
  }


  private getSecondarySortStringFromSortMap(sortMapAtStep: any) {

    let fields = this.sortFields;

    for (let i = 0; i < fields.length; i++) {
      let sortField = fields[i];

      if (sortMapAtStep[sortField].sort != null) {

        let secondarySort = sortMapAtStep[sortField].secondarySort;

        if (sortMapAtStep[sortField].sort == 'desc') {
          if(secondarySort != '' ) {
            let sortString = `${secondarySort}:`;
            sortString = sortString + "-1";
            return sortString;
          }
        } else {
          if(secondarySort != '') {
            let sortString = `${secondarySort}:`;
            sortString = sortString + "1";
            return sortString;
          }
        }
      }
    }
    return '';
  }

  private getFirstFilter(type:string): FilterField {
    try {
      let queryFilters: QueryFilter[] = this.formatRules.queryFilters[this.recordType];
      for(let queryFilter of queryFilters) {
        if(queryFilter.filterType == type) {
          for(let filterField of queryFilter.filterFields) {
            return filterField;
          }
        }
      }
      return this.defaultFilterField;
    } catch(error) {
      return this.defaultFilterField;
    }
  }

  private findFilterTemplate(filterFieldPath: string): string {
    let templateString: string = '';
    let queryFilters: QueryFilter[] = this.formatRules.queryFilters[this.recordType];
    if(_isArray(queryFilters)) {
      for(let queryFilter of queryFilters) {
          for(let filterField of queryFilter.filterFields) {
            if(filterField.path == filterFieldPath) {
              return _get(filterField,'template','');
            }
          }
      }
    }
    return templateString;
  }

  private getFilters(type:string) {
    let filterFields: FilterField[] = [];
    let queryFilters: QueryFilter[] = this.formatRules.queryFilters[this.recordType];
    if(_isArray(queryFilters)) {
      for(let queryFilter of queryFilters) {
        if(queryFilter.filterType == type) {
          for(let filterField of queryFilter.filterFields) {
            filterFields.push(filterField);
          }
        }
      }
    }
    return filterFields;
  }

  private getFirstTextFilter(): FilterField {
    return this.getFirstFilter('text');
  }

  public getTextFilters() {
    return this.getFilters('text');
  }

  public getFilterSearchDisplayed(step: any): boolean {
    let filterDisplayed = _get(this.isFilterSearchDisplayed,step,'');
    if(filterDisplayed == 'filterDisplayed') {
      return true;
    } else {
      return false;
    }
  }

  public getIsSearching(step: any): boolean {
    let searching = _get(this.isSearching,step,'');
    if(searching == 'searching') {
      return true;
    } else {
      return false;
    }
  }

  public getFilterSearchString(step: any): string {
    let filterString = _get(this.filterSearchString,step,'');
    let templateOrPath = this.findFilterTemplate(this.filterFieldPath);
    if (templateOrPath && templateOrPath.indexOf('<%') != -1) {
      const imports: any = { value: filterString};
      return this.runTemplate(templateOrPath,imports);
    }
    return filterString;
  }

  public async filterChanged(step: string) {

    if (this.dashboardTypeSelected == 'standard' || this.dashboardTypeSelected == 'workspace') {
      this.isSearching[step] = 'searching';
      this.isFilterSearchDisplayed[step] = 'filterDisplayed';
      let sortMapAtStep = this.sortMap[step];
      this.records[step].currentPage = 1;
      let stagedRecords: any;
      if(this.dashboardTypeSelected == 'workspace') {
        stagedRecords = await this.recordService.getRecords('', '', 1, this.packageType, this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      } else {
        stagedRecords = await this.recordService.getRecords(this.recordType, step, 1, '', this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      }
      let planTable: PlanTable = this.evaluatePlanTableColumns({}, {}, {}, step, stagedRecords);
      this.records[step] = planTable;
      this.isSearching[step] = '';
    }
  }

  public async resetFilterAndSearch(step: string, e: any) {
    
    if (this.dashboardTypeSelected == 'standard' || this.dashboardTypeSelected == 'workspace') {
      this.setFilterField(this.getFirstTextFilter(), e);
      this.isSearching[step] = 'searching';
      let sortMapAtStep = this.sortMap[step];
      this.filterSearchString[step] = '';
      this.records[step].currentPage = 1;
      let stagedRecords: any;
      if(this.dashboardTypeSelected == 'workspace') {
        stagedRecords = await this.recordService.getRecords('', '', 1, this.packageType, this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      } else {
        stagedRecords = await this.recordService.getRecords(this.recordType, step, 1, '', this.getSortStringFromSortMap(sortMapAtStep),this.filterFieldPath,this.getFilterSearchString(step),'',this.getSecondarySortStringFromSortMap(sortMapAtStep));
      }
      let planTable: PlanTable = this.evaluatePlanTableColumns({}, {}, {}, step, stagedRecords);
      this.records[step] = planTable;
      this.isSearching[step] = '';
    }
  }

  public setFilterField(filterField:FilterField, e: any) {
    if (e) {
      e.preventDefault();
    }
    this.filterFieldName = filterField.name;
    this.filterFieldPath = filterField.path;
  }

}


<div *ngIf="isReady">
    <ng-container>
        <div *ngFor="let workflowStep of workflowSteps">
            <div class="d-flex flex-row">
              <div *ngIf="workflowSteps.length > 1 && (dashboardTypeSelected == 'standard' || dashboardTypeSelected == 'consolidated')" class="col-md-4">
                <h2>{{ 'dashboard-heading' | i18next: {stage: workflowStep.config.workflow.stageLabel, recordTypeName: typeLabel} }}</h2>
              </div>
              <div *ngIf="workflowSteps.length == 1 && !hideWorkflowStepTitle && (dashboardTypeSelected == 'standard' || dashboardTypeSelected == 'consolidated')" class="col-md-4">
                <h2>{{ 'dashboard-heading-one-step' | i18next: {recordTypeName: typeLabel} }}</h2>
              </div>
              <ng-container *ngIf="(dashboardTypeSelected == 'standard' || dashboardTypeSelected == 'workspace') && (records[workflowStep.config.workflow.stage].totalItems > 0 || (records[workflowStep.config.workflow.stage].totalItems <= 0 && getFilterSearchDisplayed(workflowStep.config.workflow.stage)))">
                <div class="col-md-8">
                  <div class="d-flex flex-row mt-4">
                    <button class="btn btn-primary dropdown-toggle" type='button' data-bs-toggle="dropdown" aria-expanded="false" >Filter by {{ filterFieldName }}</button>
                    <ul class="dropdown-menu">
                      <li *ngFor="let filter of getTextFilters()"><a class="dropdown-item" href="#" (click)="setFilterField(filter, $event)">Filter by {{ filter.name }}</a></li>
                      <li><hr class="dropdown-divider"></li>
                      <li><a class="dropdown-item" href="#" (click)="resetFilterAndSearch(workflowStep.config.workflow.stage, $event)">{{ 'record-search-reset' | i18next }}</a></li>
                    </ul>
                    <input type="text" class="form-control" [(ngModel)]="filterSearchString[workflowStep.config.workflow.stage]" placeholder="{{ 'record-search-basic-search-placeholder' | i18next}}" (keyup.enter)="filterChanged(workflowStep.config.workflow.stage)" aria-describedby="basic-search-addon" autofocus>
                    <button class="btn btn-primary" type='button' aria-expanded="false" [disabled]="getIsSearching(workflowStep.config.workflow.stage) || getFilterSearchString(workflowStep.config.workflow.stage) == ''" (click)="filterChanged(workflowStep.config.workflow.stage)">{{ 'record-search-basic-search' | i18next }}</button>
                  </div>
                </div>
                <div class="col-md-4"></div>
              </ng-container>
            </div>
            <div *ngIf="records[workflowStep.config.workflow.stage] != null">
                <div *ngIf="records[workflowStep.config.workflow.stage].totalItems <= 0" class="padding-bottom-10" >
                    {{ 'no-records' | i18next: {stage: workflowStep.config.workflow.stageLabel.toLowerCase(), recordTypeName: typeLabel.toLowerCase()} }}
                </div>
                <div *ngIf="records[workflowStep.config.workflow.stage].totalItems > 0">
                <table class="table">
                    <thead>
                    <tr>
                    <th *ngFor="let rowConfig of tableConfig[workflowStep.config.workflow.stage]"> 
                        <sort *ngIf="enableSort" [title]="rowConfig.title | i18next" [variable]="rowConfig.variable" [step]="workflowStep.config.workflow.stage" [sort]="getSortStateFromSortMap(sortMap,workflowStep,rowConfig)" [secondarySort]="getSecondarySortStateFromSortMap(sortMap,workflowStep,rowConfig)" (sortChanged)="sortChanged($event)"> </sort>
                        <span *ngIf="!enableSort" class="dashboard-heading-no-sort">{{rowConfig.title | i18next}}</span>
                    </th>
                    </tr>
                    </thead>
                    <tbody *ngFor="let plan of records[workflowStep.config.workflow.stage].items">
                    <tr><td *ngFor="let rowConfig of tableConfig[workflowStep.config.workflow.stage]" [innerHtml]="plan[rowConfig.variable]"></td></tr>
                    </tbody>
                </table>

                 <pagination *ngIf="records[workflowStep.config.workflow.stage].totalItems > 0" [directionLinks]="false" [boundaryLinks]="true" [totalItems]="records[workflowStep.config.workflow.stage].totalItems"
                            [(ngModel)]="records[workflowStep.config.workflow.stage].currentPage" (pageChanged)="pageChanged($event,workflowStep.config.workflow.stage)" class="pagination-sm" [maxSize]="10"></pagination>
                </div>
            </div>
        </div>
    </ng-container>
</div>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""