@universis/ngx-tables 0.6.13 → 0.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/bundles/universis-ngx-tables.umd.js +1037 -1026
  2. package/bundles/universis-ngx-tables.umd.js.map +1 -1
  3. package/bundles/universis-ngx-tables.umd.min.js +1 -1
  4. package/bundles/universis-ngx-tables.umd.min.js.map +1 -1
  5. package/esm2015/lib/components/advanced-list/advanced-list.component.js +2 -2
  6. package/esm2015/lib/components/advanced-row-action/advanced-row-action.component.js +12 -3
  7. package/esm2015/lib/components/advanced-select/advanced-select.component.js +2 -2
  8. package/esm2015/lib/components/advanced-table/advanced-table.component.js +2 -2
  9. package/esm2015/lib/components/advanced-table-modal/advanced-table-modal-base.component.js +2 -2
  10. package/esm2015/lib/i18n/tables.el.js +2 -1
  11. package/esm2015/lib/i18n/tables.en.js +2 -1
  12. package/esm2015/public_api.js +1 -4
  13. package/esm5/lib/components/advanced-list/advanced-list.component.js +2 -2
  14. package/esm5/lib/components/advanced-row-action/advanced-row-action.component.js +12 -3
  15. package/esm5/lib/components/advanced-select/advanced-select.component.js +2 -2
  16. package/esm5/lib/components/advanced-table/advanced-table.component.js +2 -2
  17. package/esm5/lib/components/advanced-table-modal/advanced-table-modal-base.component.js +2 -2
  18. package/esm5/lib/i18n/tables.el.js +2 -1
  19. package/esm5/lib/i18n/tables.en.js +2 -1
  20. package/esm5/public_api.js +1 -4
  21. package/fesm2015/universis-ngx-tables.js +1428 -1417
  22. package/fesm2015/universis-ngx-tables.js.map +1 -1
  23. package/fesm5/universis-ngx-tables.js +1546 -1535
  24. package/fesm5/universis-ngx-tables.js.map +1 -1
  25. package/lib/components/advanced-row-action/advanced-row-action.component.d.ts +4 -1
  26. package/lib/components/advanced-table-modal/advanced-table-modal-base.component.d.ts +1 -1
  27. package/lib/i18n/tables.el.d.ts +1 -0
  28. package/lib/i18n/tables.en.d.ts +1 -0
  29. package/package.json +16 -15
  30. package/public_api.d.ts +0 -3
  31. package/universis-ngx-tables.metadata.json +1 -1
@@ -4,16 +4,16 @@ import 'datatables.net';
4
4
  import { template, at } from 'lodash';
5
5
  import 'datatables.net-scroller';
6
6
  import 'rxjs/add/observable/combineLatest';
7
- import { BehaviorSubject } from 'rxjs';
8
7
  import { HttpClient } from '@angular/common/http';
9
- import { AngularDataContext } from '@themost/angular';
10
8
  import { ClientDataQueryable, ResponseError, TextUtils } from '@themost/client';
9
+ import { BehaviorSubject } from 'rxjs';
10
+ import { AngularDataContext } from '@themost/angular';
11
11
  import { __awaiter, __generator, __extends, __values, __assign, __spread } from 'tslib';
12
- import { Injectable, Pipe, Component, Input, Output, EventEmitter, ElementRef, ViewChild, ViewEncapsulation, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, Directive, HostListener, ChangeDetectionStrategy, ChangeDetectorRef, InjectionToken, Inject, Injector } from '@angular/core';
12
+ import { Injectable, Pipe, Component, ElementRef, Input, ViewChild, ViewEncapsulation, EventEmitter, Output, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, Directive, HostListener, ChangeDetectorRef, InjectionToken, Inject, Injector, ChangeDetectionStrategy } from '@angular/core';
13
13
  import { DatePipe, CommonModule } from '@angular/common';
14
14
  import { TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
15
15
  import { FormArray, FormBuilder, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
16
- import { TemplatePipe, LoadingService, AppEventService, ErrorService, ModalService, ToastService, SharedModule, ConfigurationService, DIALOG_BUTTONS, UserActivityService, UserStorageService } from '@universis/common';
16
+ import { TemplatePipe, LoadingService, ErrorService, DIALOG_BUTTONS, ModalService, UserActivityService, ToastService, AppEventService, UserStorageService, ConfigurationService, SharedModule } from '@universis/common';
17
17
  import { RouterModalOkCancel, RouterModalModule } from '@universis/common/routing';
18
18
  import { ServiceUrlPreProcessor, TranslatePreProcessor, AdvancedFormsModule } from '@universis/forms';
19
19
  import { FormioModule } from 'angular-formio';
@@ -1583,7 +1583,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1583
1583
  { type: Component, args: [{
1584
1584
  // tslint:disable-next-line: component-selector
1585
1585
  selector: 'app-advanced-table',
1586
- template: "\n <table #table class=\"dataTable nowrap mr-0\">\n </table>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n ",
1586
+ template: "\n <table #table class=\"dataTable\">\n </table>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n ",
1587
1587
  encapsulation: ViewEncapsulation.None,
1588
1588
  styles: ["table.dataTable thead .sorting{background-image:none}table.dataTable thead .sorting_asc{background-position:95% 60%;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsSAAALEgHS3X78AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEtJREFUKJFjYBgywAOKMQALFjE/BgaGTCibjYGBYRM+kz0ZGBh2MTAw8DAwMHAxMDBsY2BgCCBGMQzg1IRNMV5NuVAJXIALqmYwAgBBkAlPRCLcLwAAAABJRU5ErkJggg==)}table.dataTable thead .sorting_desc{background-position:95% 60%;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAArzAAAK8wHvFRX1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAFNJREFUKJHVzTEKgDAQRNGHZfBg2sSTeDMLKwXPYuVJbBKQQEyrH6bZ+cPyWWaElz4kR5cOJ1b0FXnBVRYjjmIUsGGqvX6OmnImYk+JLTkzpPyBGwrtCvfBe56nAAAAAElFTkSuQmCC)}table.dataTable thead th{color:#73818e;font-size:.75rem;font-weight:600;padding-top:16px;padding-bottom:4px;border-bottom:none;padding-left:8px}table.dataTable tbody tr:first-child td:first-child{border-radius:6px 0}table.dataTable tbody tr:first-child td:last-child{border-radius:0 6px}table.dataTable tbody tr{border-radius:6px}table.dataTable tbody tr td:first-child{border-left:1px solid #c2cfd6}table.dataTable tbody tr td:last-child{border-right:1px solid #c2cfd6}table.dataTable tbody tr td{padding-top:8px;padding-bottom:8px;border-top:1px solid #c2cfd6}table.dataTable tbody tr:last-child td:first-child{border-radius:0 0 0 6px}table.dataTable tbody tr:last-child td:last-child{border-radius:0 0 6px}table.dataTable tbody tr:last-child td{border-bottom:1px solid #c2cfd6}table.dataTable td.dataTables_empty{border:none!important}table.dataTable.no-footer{border-bottom:none}.dataTables_paginate .btn.previous{margin-right:8px}.dataTables_paginate .btn.next{margin-left:8px}.dataTables_info,.dataTables_paginate{margin-top:1rem}.dataTables_paginate span .btn{border-radius:1.5rem}.dataTables_filter{display:none}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:0;overflow:auto}.dataTables_paginate{display:none}.dataTable.processing{opacity:15%}.dataTables_wrapper .dataTables_processing{background:0 0;position:absolute;display:inline-block;top:25%;z-index:5;color:#73818e}.text-decoration-line-through{text-decoration:line-through!important}tr.removed .checkbox+label{visibility:hidden}"]
1589
1589
  }] }
@@ -1634,336 +1634,252 @@ var AdvancedTableComponent = /** @class */ (function () {
1634
1634
  return AdvancedTableComponent;
1635
1635
  }());
1636
1636
 
1637
- // important: export this const due to AOT compilation errors
1638
- // see more https://angular.io/guide/aot-metadata-errors#only-initialized-variables
1639
- var AdvancedTableModalBaseTemplate = "\n<div>\n <!-- search -->\n <div class=\"row mt-3\">\n <div class=\"col-12 col-lg-3\">\n <div class=\"input-group mb-3\">\n <input spellcheck=\"false\" type=\"text\"\n (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"searchText\"\n class=\"form-control bg-gray-100 border-0\"\n placeholder=\"{{'Tables.SearchPlaceholder' | translate}}\" aria-label=\"Search\" aria-describedby=\"basic-addon2\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-default bg-gray-100 border-0\" type=\"button\">\n <i class=\"fa fa-search text-secondary\"></i>\n </button>\n </div>\n </div>\n </div>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n\n </div>\n </div>\n <div class=\"col-12 col-lg-5\">\n <div class=\"btn-toolbar\">\n <button class=\"btn btn-gray-100\">\n <i class=\"fa fa-sliders-h pr-2 text-secondary\" aria-hidden=\"true\"></i>{{'Tables.Filters' | translate}}\n </button>\n <div #dropdownFilter class=\"dropdown ml-3\">\n <button class=\"btn btn-gray-100 dropdown-toggle\"\n type=\"button\" id=\"dropdownDefaultFilters\"\n data-toggle=\"dropdown\" dropdownToggle>\n {{ this.defaultFilter.name | translate }}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownDefaultFilters\">\n <button type=\"button\" class=\"dropdown-item\" *ngFor=\"let filter of defaultFilters\" (click)=\"onFilterSelect(filter)\">\n {{ filter.name | translate }}\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col text-lg-right mt-3 mt-lg-0\">\n <button [disabled]=\"true\" class=\"btn rounded-pill btn-outline-theme\">\n <span class=\"pr-2 font-lg\">+</span><span [translate]=\"'Tables.AddItem'\"></span>\n </button>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\" [ngClass]=\"{ 'component-loading': loading}\">\n <app-advanced-table #advancedTable (init)=\"onTableInit($event)\"\n (load)=\"onDataLoad($event)\"\n [selectable]=\"true\"\n [multipleSelect]=\"true\"\n [scrollX]=\"false\" [scrollY]=\"320\"\n [pageLength]=\"pageLength\"\n [scrollable]=\"false\" [showFooter]=\"false\"\n [showActions]=\"false\" [lengthMenu]=\"lengthMenu\"\n [config]=\"tableConfig\" [configSrc]=\"tableConfigSrc\"></app-advanced-table>\n </div>\n </div>\n <div class=\"row mt-3 table-custom-pager\">\n <div class=\"col-12 d-flex\" *ngIf=\"recordsTotal\">\n <div class=\"mt-2 ml-auto mr-3 text-secondary\" [translate]=\"'Tables.RecordsPerPage'\"></div>\n <div #dropdownLength class=\"dropdown mr-3\">\n <button class=\"btn btn-gray-100 dropdown-toggle\"\n type=\"button\" id=\"dropdownPageSize\" data-toggle=\"dropdown\"\n dropdownToggle>\n {{pageLength}}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownPageSize\">\n <button (click)=\"setLength(item)\"\n class=\"dropdown-item dropdown-item-theme\"\n type=\"button\" *ngFor=\"let item of lengthMenu\">{{item}}</button>\n </div>\n </div>\n <div class=\"mt-2 mr-2\" [translate]=\"'Tables.PageInfo'\" [translateParams]=\"pageInfo\"></div>\n <button [disabled]=\"pageInfo && pageInfo.page === 0\" class=\"btn text-nowrap\" (click)=\"firstPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===0\" class=\"btn\" (click)=\"previousPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn\" (click)=\"nextPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn text-nowrap\" (click)=\"lastPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n </div>\n </div>\n </div>\n";
1640
- var AdvancedTableModalBaseComponent = /** @class */ (function (_super) {
1641
- __extends(AdvancedTableModalBaseComponent, _super);
1642
- function AdvancedTableModalBaseComponent(_router, _activatedRoute, _context, advancedFilterValueProvider, datePipe) {
1643
- var _this = _super.call(this, _router, _activatedRoute) || this;
1644
- _this._context = _context;
1645
- _this.advancedFilterValueProvider = advancedFilterValueProvider;
1646
- _this.datePipe = datePipe;
1647
- _this.pageLength = 25;
1648
- _this.lengthMenu = [5, 10, 25, 50, 100];
1649
- _this.recordsTotal = 0;
1650
- _this.loading = false;
1651
- _this.recordsFiltered = 0;
1652
- _this.defaultFilters = [AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER];
1653
- _this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
1654
- _this.pageInfo = {
1655
- serverSide: true
1656
- };
1657
- _this.modalClass = 'modal-xl modal-table';
1658
- _this._template = new TemplatePipe();
1659
- return _this;
1637
+ var AdvancedListComponent = /** @class */ (function () {
1638
+ function AdvancedListComponent(_context, _translateService, _activatedRoute, _errorService, _toastService, _modalService, _userActivityService) {
1639
+ this._context = _context;
1640
+ this._translateService = _translateService;
1641
+ this._activatedRoute = _activatedRoute;
1642
+ this._errorService = _errorService;
1643
+ this._toastService = _toastService;
1644
+ this._modalService = _modalService;
1645
+ this._userActivityService = _userActivityService;
1646
+ this.allowSaveOption = true;
1660
1647
  }
1661
- AdvancedTableModalBaseComponent.prototype.ngAfterViewInit = function () {
1662
- //
1663
- };
1664
- AdvancedTableModalBaseComponent.prototype._getInputs = function (componentType) {
1665
- var props = componentType.__prop__metadata__;
1666
- var inputs = [];
1667
- if (props == null) {
1668
- return inputs;
1648
+ AdvancedListComponent.prototype.ngOnDestroy = function () {
1649
+ if (this.dataSubscription) {
1650
+ this.dataSubscription.unsubscribe();
1651
+ }
1652
+ if (this.reloadSubscription) {
1653
+ this.reloadSubscription.unsubscribe();
1669
1654
  }
1670
- Object.keys(props).forEach(function (prop) {
1671
- var member = props[prop][0];
1672
- if (member.ngMetadataName === 'Input') {
1673
- inputs.push(prop);
1674
- }
1675
- });
1676
- return inputs.sort();
1677
- };
1678
- AdvancedTableModalBaseComponent.prototype.hasInputs = function () {
1679
- return [];
1680
- };
1681
- AdvancedTableModalBaseComponent.prototype.ngOnInit = function () {
1682
- var _this = this;
1683
- this.okButtonText = 'Tables.Apply';
1684
- this.cancelButtonText = 'Tables.Cancel';
1685
- // get route data
1686
- this.subscription = this.activatedRoute.data.subscribe(function (data) {
1687
- // set modal title if any
1688
- if (data.title) {
1689
- _this.modalTitle = data.title;
1690
- }
1691
- if (data.config) {
1692
- _this.tableConfig = data.config;
1693
- }
1694
- if (_this.tableConfig) {
1695
- _this.defaultFilters.push.apply(_this.defaultFilters, _this.tableConfig.searches);
1696
- }
1697
- // important: use hasInputs due to AOT compilation. Metadata properties cannot be used (e.g. @Input())
1698
- // because there are empty during runtime
1699
- // so we need to define manually input properties that are going to be bind through this process
1700
- // bind all inputs
1701
- var inputs = _this.hasInputs();
1702
- inputs.forEach(function (input) {
1703
- if (Object.prototype.hasOwnProperty.call(data, input)) {
1704
- _this[input] = data[input];
1705
- }
1706
- });
1707
- _this.configChangesSubscription = _this.advancedTable.configChanges.subscribe(function (config) {
1708
- if (_this.tableConfig) {
1709
- // reset default filter
1710
- _this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
1711
- // init filter
1712
- _this.defaultFilters = [AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER];
1713
- // add extra filters
1714
- _this.defaultFilters.push.apply(_this.defaultFilters, _this.tableConfig.searches);
1715
- }
1716
- });
1717
- });
1718
- };
1719
- AdvancedTableModalBaseComponent.prototype.cancel = function () {
1720
- return this.close();
1721
- };
1722
- AdvancedTableModalBaseComponent.prototype.ok = function () {
1723
- return this.close();
1724
- };
1725
- AdvancedTableModalBaseComponent.prototype.ngOnDestroy = function () {
1726
1655
  if (this.subscription) {
1727
1656
  this.subscription.unsubscribe();
1728
1657
  }
1729
1658
  };
1730
- AdvancedTableModalBaseComponent.prototype.onDataLoad = function (data) {
1731
- this.recordsTotal = data.recordsTotal;
1732
- this.recordsFiltered = data.recordsFiltered;
1733
- // get first page info (because page is not going to be fired for first page)
1734
- if (data.recordsTotal > 0 && this.pageInfo.recordsTotal === 0) {
1735
- this.pageInfo.recordsTotal = data.recordsTotal;
1736
- }
1737
- };
1738
- AdvancedTableModalBaseComponent.prototype.previousPage = function () {
1739
- // go to next page
1740
- // noinspection TypeScriptValidateJSTypes
1741
- this.advancedTable.dataTable.page('previous').draw('page');
1742
- };
1743
- AdvancedTableModalBaseComponent.prototype.nextPage = function () {
1744
- // go to next page
1745
- // noinspection TypeScriptValidateJSTypes
1746
- this.advancedTable.dataTable.page('next').draw('page');
1747
- };
1748
- AdvancedTableModalBaseComponent.prototype.onTableInit = function (dataTable) {
1749
- var self = this;
1750
- // get initial page info
1751
- var initialPageInfo = dataTable.page.info();
1752
- initialPageInfo.start += 1;
1753
- self.pageInfo = initialPageInfo;
1754
- // change emptyTableMessage
1755
- dataTable.context[0].oLanguage.sEmptyTable = this.emptyTable.nativeElement.innerHTML;
1756
- // bind page change event
1757
- dataTable.on('page.dt', function () {
1758
- var pageInfo = dataTable.page.info();
1759
- pageInfo.start += 1;
1760
- self.pageInfo = pageInfo;
1761
- });
1762
- // bind draw change event
1763
- dataTable.on('draw.dt', function () {
1764
- // for future use
1765
- self.loading = false;
1766
- var pageInfo = dataTable.page.info();
1767
- pageInfo.start += 1;
1768
- self.pageInfo = pageInfo;
1769
- });
1770
- };
1771
- AdvancedTableModalBaseComponent.prototype.firstPage = function () {
1772
- // go to first page
1773
- // noinspection TypeScriptValidateJSTypes
1774
- this.advancedTable.dataTable.page('first').draw('page');
1775
- };
1776
- AdvancedTableModalBaseComponent.prototype.lastPage = function () {
1777
- // go to last page
1778
- // noinspection TypeScriptValidateJSTypes
1779
- this.advancedTable.dataTable.page('last').draw('page');
1780
- };
1781
- AdvancedTableModalBaseComponent.prototype.setLength = function (value) {
1782
- this.pageLength = value;
1783
- this.advancedTable.dataTable.page.len(value).draw();
1784
- };
1785
- AdvancedTableModalBaseComponent.prototype.onKeyUp = function (event) {
1786
- if (event.code === 'Enter') {
1787
- // loading
1788
- this.loading = true;
1789
- this.advancedTable.search(event.target.value);
1790
- }
1791
- };
1792
- /**
1793
- *
1794
- * Reads the modal table and returns a list of filters to use in the table
1795
- * query.
1796
- *
1797
- * @param tableConfig {object} The table configuration from json file
1798
- * @param defaultFilterValues {object} A list of default filters
1799
- * @param {object} searchItem The searchItem to use
1800
- *
1801
- */
1802
- AdvancedTableModalBaseComponent.prototype.getFilters = function (tableConfig, defaultFilterValues, searchItem) {
1803
- if (defaultFilterValues === void 0) { defaultFilterValues = {}; }
1804
- // Do nothing in absence of configuration.
1805
- if (!tableConfig || !Array.isArray(tableConfig.criteria)) {
1806
- return [];
1807
- }
1808
- if (searchItem.filter == null) {
1809
- return [];
1810
- }
1811
- var matchedCriterion = tableConfig.criteria.find(function (criterion) {
1812
- return Object.prototype.hasOwnProperty.call(searchItem.filter, criterion.name);
1813
- });
1814
- if (matchedCriterion == null) {
1815
- return [];
1816
- }
1817
- var value = searchItem.filter[matchedCriterion.name];
1818
- var criterionSafeName = matchedCriterion.name !== null
1819
- ? matchedCriterion.name.toString()
1820
- : '';
1821
- var applicableFilter;
1822
- // Raw dates should be transformed to a specific format
1823
- if (criterionSafeName.includes('GMT')) {
1824
- var newDate = this.datePipe.transform(criterionSafeName, 'MM/dd/yyyy');
1825
- applicableFilter = this._template.transform(matchedCriterion.filter, {
1826
- value: newDate
1827
- });
1828
- }
1829
- else if (criterionSafeName !== 'undefined') {
1830
- applicableFilter = (this._template.transform(matchedCriterion.filter, Object.assign({
1831
- value: value
1832
- }, defaultFilterValues)));
1833
- }
1834
- else {
1835
- applicableFilter = '';
1836
- }
1837
- return [applicableFilter];
1838
- };
1839
- AdvancedTableModalBaseComponent.prototype.onFilterSelect = function (value) {
1840
- this.advancedSearch(value);
1841
- };
1842
- /**
1843
- *
1844
- * Runs a filter against the modal table
1845
- *
1846
- * @param {object} filter The filter to use in the search
1847
- *
1848
- */
1849
- AdvancedTableModalBaseComponent.prototype.advancedSearch = function (filter) {
1659
+ AdvancedListComponent.prototype.ngOnInit = function () {
1850
1660
  return __awaiter(this, void 0, void 0, function () {
1851
- var defaultFilterValues, err_1, expressions, predefinedCriteria, query;
1661
+ var metadata_1, err_1;
1662
+ var _this = this;
1852
1663
  return __generator(this, function (_a) {
1853
1664
  switch (_a.label) {
1854
1665
  case 0:
1855
- // Do nothing in absence of configuration.
1856
- if (!this.tableConfig && !Array.isArray(this.tableConfig.criteria)) {
1857
- console.warn('No table configuration available', this.tableConfig);
1858
- return [2 /*return*/];
1859
- }
1860
- _a.label = 1;
1666
+ _a.trys.push([0, 2, , 3]);
1667
+ return [4 /*yield*/, this._context.getMetadata()];
1861
1668
  case 1:
1862
- _a.trys.push([1, 3, , 4]);
1863
- return [4 /*yield*/, this.advancedFilterValueProvider.getValues()];
1864
- case 2:
1865
- defaultFilterValues = _a.sent();
1866
- return [3 /*break*/, 4];
1867
- case 3:
1868
- err_1 = _a.sent();
1869
- defaultFilterValues = {};
1870
- return [3 /*break*/, 4];
1871
- case 4:
1872
- expressions = [];
1873
- if (filter) {
1874
- this.defaultFilter = filter;
1875
- predefinedCriteria = this.getFilters(this.tableConfig, defaultFilterValues, filter);
1876
- }
1877
- else {
1878
- // Empty a falsy filter resets the results
1879
- this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
1880
- }
1881
- // search filter is applied separately, there is no need to add here.
1882
- expressions.push(predefinedCriteria);
1883
- query = this._context.model(this.advancedTable.config.model).asQueryable();
1884
- query.setParam('filter', expressions.join(' and ')).prepare();
1885
- this.advancedTable.query = query;
1886
- this.advancedTable.fetch();
1887
- return [2 /*return*/];
1669
+ metadata_1 = _a.sent();
1670
+ // get route data
1671
+ this.dataSubscription = this._activatedRoute.data.subscribe(function (routeData) {
1672
+ // get entityType
1673
+ var re = new RegExp("^" + routeData.model + "$", 'ig');
1674
+ var entitySet = metadata_1.EntityContainer.EntitySet.find(function (x) {
1675
+ return re.test(x.Name);
1676
+ });
1677
+ // if entity type is null
1678
+ if (entitySet == null) {
1679
+ // navigate to error
1680
+ return _this._errorService.navigateToError(new ResponseError('EntitySet Not Found', 404));
1681
+ }
1682
+ // get entity type
1683
+ var entityType = metadata_1.EntityType.find(function (x) {
1684
+ return x.Name === entitySet.EntityType;
1685
+ });
1686
+ if (entityType == null) {
1687
+ return _this._errorService.navigateToError(new ResponseError('EntityType Not Found', 404));
1688
+ }
1689
+ if (routeData.searchConfiguration) {
1690
+ if (Object.prototype.hasOwnProperty.call(routeData.searchConfiguration, 'allowSave')) {
1691
+ _this.allowSaveOption = routeData.searchConfiguration.allowSave;
1692
+ }
1693
+ _this.searchConfiguration = routeData.searchConfiguration;
1694
+ }
1695
+ if (routeData.tableConfiguration) {
1696
+ _this.tableConfiguration = routeData.tableConfiguration;
1697
+ }
1698
+ if (routeData.description) {
1699
+ _this.description = _this._translateService.instant(routeData.description);
1700
+ }
1701
+ if (routeData.longDescription) {
1702
+ _this.longDescription = _this._translateService.instant(routeData.longDescription);
1703
+ }
1704
+ if (routeData.category) {
1705
+ _this.category = _this._translateService.instant(routeData.category);
1706
+ }
1707
+ // clone default configuration
1708
+ var defaultConfiguration = AdvancedTableConfiguration.cast(_this.tableConfiguration, true);
1709
+ // correct edit button link
1710
+ var column = defaultConfiguration.columns.find(function (col) {
1711
+ return col.formatter === 'ButtonFormatter' && col.formatString === '(modal:edit)';
1712
+ });
1713
+ if (column) {
1714
+ var url_1 = [];
1715
+ _this._activatedRoute.snapshot.pathFromRoot.forEach(function (route) {
1716
+ url_1.push.apply(url_1, route.url);
1717
+ });
1718
+ column.formatString = "#/" + url_1.join('/') + "/(modal:${id}/edit)";
1719
+ }
1720
+ // create list configuration by assigning list entity set
1721
+ _this.table.config = Object.assign({
1722
+ model: entitySet.Name
1723
+ }, defaultConfiguration);
1724
+ // fetch data
1725
+ _this.table.fetch(true);
1726
+ // do reload by using hidden fragment e.g. /classes#reload
1727
+ _this.reloadSubscription = _this._activatedRoute.fragment.subscribe(function (fragment) {
1728
+ if (fragment && fragment === 'reload') {
1729
+ _this._toastService.show(_this.description, _this._translateService.instant('Settings.OperationCompleted'));
1730
+ _this.table.fetch(true);
1731
+ }
1732
+ });
1733
+ // finally add user activity
1734
+ _this._userActivityService.setItem({
1735
+ category: _this.category,
1736
+ description: _this.description,
1737
+ url: window.location.hash.substring(1),
1738
+ dateCreated: new Date
1739
+ });
1740
+ });
1741
+ return [3 /*break*/, 3];
1742
+ case 2:
1743
+ err_1 = _a.sent();
1744
+ console.error(err_1);
1745
+ return [2 /*return*/, this._errorService.showError(err_1)];
1746
+ case 3: return [2 /*return*/];
1888
1747
  }
1889
1748
  });
1890
1749
  });
1891
1750
  };
1892
- AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER = {
1893
- name: 'Tables.All',
1894
- filter: null
1751
+ /**
1752
+ * Data load event handler of advanced table component
1753
+ * @param {AdvancedTableDataResult} data
1754
+ */
1755
+ AdvancedListComponent.prototype.onDataLoad = function (data) {
1756
+ this.recordsTotal = data.recordsTotal;
1895
1757
  };
1896
- AdvancedTableModalBaseComponent.decorators = [
1758
+ /**
1759
+ * Remove selected items
1760
+ */
1761
+ AdvancedListComponent.prototype.remove = function () {
1762
+ var _this = this;
1763
+ if (this.table && this.table.selected && this.table.selected.length) {
1764
+ // get items to remove
1765
+ var items_1 = this.table.selected;
1766
+ return this._modalService.showWarningDialog(this._translateService.instant('Tables.RemoveItemsTitle'), this._translateService.instant('Tables.RemoveItemsMessage'), DIALOG_BUTTONS.OkCancel).then(function (result) {
1767
+ if (result === 'ok') {
1768
+ _this._context.model(_this.table.config.model).remove(items_1).then(function () {
1769
+ _this._toastService.show(_this.description + ':' + _this._translateService.instant('Tables.RemoveItemMessage.title'), _this._translateService.instant((items_1.length === 1 ?
1770
+ 'Tables.RemoveItemMessage.one' : 'Tables.RemoveItemMessage.many'), { value: items_1.length }));
1771
+ _this.table.fetch(true);
1772
+ }).catch(function (err) {
1773
+ _this._errorService.showError(err, {
1774
+ continueLink: '.'
1775
+ });
1776
+ });
1777
+ }
1778
+ });
1779
+ }
1780
+ };
1781
+ AdvancedListComponent.decorators = [
1897
1782
  { type: Component, args: [{
1898
- // tslint:disable-next-line: component-selector
1899
- selector: 'app-advanced-table-modal',
1900
- template: AdvancedTableModalBaseTemplate,
1901
- styles: ["\n\n "]
1783
+ selector: 'app-advanced-list',
1784
+ template: "<div>\n <div class=\"row\" *ngIf=\"description\">\n <div class=\"col-auto\">\n <h2>{{description}}</h2>\n <p *ngIf=\"longDescription\">{{longDescription}}</p>\n </div>\n </div>\n <div class=\"row\" *ngIf=\"searchConfiguration\">\n <div class=\"col-12\" [ngVar]=\"{}\" #filter=\"ngVar\">\n <app-advanced-table-search #advancedSearch [(filter)]=\"filter.value\" [collapsed]=\"true\" [table]=\"table\" [allowSave]=\"allowSaveOption\">\n <advanced-search>\n <app-advanced-search-form [form]=\"searchConfiguration\" (filterChange)=\"advancedSearch.asyncAdvancedSearch()\" #search [(filter)]=\"filter.value\"></app-advanced-search-form>\n </advanced-search>\n </app-advanced-table-search>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-3\">\n <a *ngIf=\"table && table.selected && table.selected.length\"\n class=\"text-danger text-decoration-none mr-2\" href=\"javascript:void(0)\" (click)=\"remove()\">\n <span>-</span><span>&nbsp;</span><span [translate]=\"'Tables.RemoveItem'\"></span>\n </a>\n <a class=\"text-indigo text-decoration-none\" [routerLink]=\"['.', { outlets:{ modal:'add'} }]\">\n <span>+</span><span>&nbsp;</span><span [translate]=\"'Tables.AddItem'\"></span>\n </a>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12 mb-4\">\n <app-advanced-table [selectable]=\"true\" #table\n [showFooter]=\"false\"\n (load)=\"onDataLoad($event)\" [height]=\"600\"></app-advanced-table>\n </div>\n </div>\n <router-modal></router-modal>\n</div>\n"
1902
1785
  }] }
1903
1786
  ];
1904
1787
  /** @nocollapse */
1905
- AdvancedTableModalBaseComponent.ctorParameters = function () { return [
1906
- { type: Router },
1907
- { type: ActivatedRoute },
1788
+ AdvancedListComponent.ctorParameters = function () { return [
1908
1789
  { type: AngularDataContext },
1909
- { type: AdvancedFilterValueProvider },
1910
- { type: DatePipe }
1790
+ { type: TranslateService },
1791
+ { type: ActivatedRoute },
1792
+ { type: ErrorService },
1793
+ { type: ToastService },
1794
+ { type: ModalService },
1795
+ { type: UserActivityService }
1911
1796
  ]; };
1912
- AdvancedTableModalBaseComponent.propDecorators = {
1913
- advancedTable: [{ type: ViewChild, args: ['advancedTable',] }],
1914
- emptyTable: [{ type: ViewChild, args: ['emptyTable',] }],
1915
- dropdownFilter: [{ type: ViewChild, args: ['dropdownFilter',] }],
1916
- dropdownLength: [{ type: ViewChild, args: ['dropdownLength',] }],
1917
- tableConfig: [{ type: Input, args: ['tableConfig',] }],
1918
- tableConfigSrc: [{ type: Input, args: ['tableConfigSrc',] }],
1919
- pageLength: [{ type: Input, args: ['pageLength',] }],
1920
- searchText: [{ type: Input, args: ['searchText',] }],
1921
- lengthMenu: [{ type: Input, args: ['lengthMenu',] }],
1922
- defaultFilter: [{ type: Input, args: ['defaultFilter',] }]
1797
+ AdvancedListComponent.propDecorators = {
1798
+ entitySet: [{ type: Input, args: ['entitySet',] }],
1799
+ category: [{ type: Input, args: ['category',] }],
1800
+ description: [{ type: Input, args: ['description',] }],
1801
+ longDescription: [{ type: Input, args: ['longDescription',] }],
1802
+ tableConfiguration: [{ type: Input, args: ['tableConfiguration',] }],
1803
+ searchConfiguration: [{ type: Input, args: ['searchConfiguration',] }],
1804
+ table: [{ type: ViewChild, args: ['table',] }],
1805
+ allowSaveOption: [{ type: Input, args: ['allowSaveOption',] }]
1923
1806
  };
1924
- return AdvancedTableModalBaseComponent;
1925
- }(RouterModalOkCancel));
1807
+ return AdvancedListComponent;
1808
+ }());
1926
1809
 
1927
- var AddItemsComponent = /** @class */ (function (_super) {
1928
- __extends(AddItemsComponent, _super);
1929
- function AddItemsComponent(router, activatedRoute, _errorService, _modalService, _appEvent, _toastService, _loadingService, _translateService, _context) {
1810
+ var AdvancedRowActionComponent = /** @class */ (function (_super) {
1811
+ __extends(AdvancedRowActionComponent, _super);
1812
+ function AdvancedRowActionComponent(router, activatedRoute, _translateService, _context, _errorService, _modalService, _appEvent) {
1930
1813
  var _this = _super.call(this, router, activatedRoute) || this;
1814
+ _this._translateService = _translateService;
1815
+ _this._context = _context;
1931
1816
  _this._errorService = _errorService;
1932
1817
  _this._modalService = _modalService;
1933
1818
  _this._appEvent = _appEvent;
1934
- _this._toastService = _toastService;
1935
- _this._loadingService = _loadingService;
1936
- _this._translateService = _translateService;
1937
- _this._context = _context;
1819
+ _this.modalIcon = 'fas fa-project-diagram';
1820
+ _this.progressType = 'indigo';
1821
+ _this.errorMessage = 'Tables.Actions.CompletedWithErrors';
1938
1822
  _this.loading = false;
1939
- _this.items = [];
1940
- _this.messages = [];
1823
+ _this.refresh = new EventEmitter();
1941
1824
  // set modal size
1942
1825
  _this.modalClass = 'modal-lg';
1943
- _this.okButtonDisabled = true;
1826
+ // set modal title
1827
+ _this.modalTitle = 'Tables.Actions.Label';
1828
+ // disable ok button
1829
+ _this.okButtonDisabled = false;
1830
+ // set button text
1831
+ _this.okButtonText = 'Tables.Actions.Start';
1944
1832
  return _this;
1945
1833
  }
1946
- AddItemsComponent.prototype.ngOnInit = function () {
1834
+ Object.defineProperty(AdvancedRowActionComponent.prototype, "form", {
1835
+ get: function () {
1836
+ return this.formComponent;
1837
+ },
1838
+ enumerable: true,
1839
+ configurable: true
1840
+ });
1841
+ AdvancedRowActionComponent.prototype.ngOnInit = function () {
1947
1842
  var _this = this;
1948
- this.selectedSubscription = this.selectComponent.advancedTable.selectedItems.subscribe(function (items) {
1949
- if (_this.formName == null) {
1950
- _this.okButtonDisabled = items.length === 0;
1843
+ this.refreshSubscription = this.refresh.subscribe(function (value) {
1844
+ if (value && value.progress) {
1845
+ var progress = 0;
1846
+ if (value.progress < 0) {
1847
+ progress = 0;
1848
+ }
1849
+ else if (value.progress > 100) {
1850
+ progress = 100;
1851
+ }
1852
+ else {
1853
+ progress = value.progress;
1854
+ }
1855
+ _this.progressComponent.value = progress;
1856
+ _this.showProgress();
1951
1857
  }
1952
1858
  });
1953
- if (this.formName != null) {
1954
- this.formChangeSubscription = this.formComponent.form.change.subscribe(function (event) {
1955
- if (Object.prototype.hasOwnProperty.call(event, 'isValid')) {
1956
- // enable or disable button based on form status
1957
- _this.okButtonDisabled = (!event.isValid);
1859
+ };
1860
+ AdvancedRowActionComponent.prototype.ngAfterViewInit = function () {
1861
+ var _this = this;
1862
+ if (this.formComponent && this.formComponent.form) {
1863
+ this.okButtonDisabled = true;
1864
+ this.invalidSubscription = this.formComponent.form.change.subscribe(function (event) {
1865
+ if (Object.prototype.hasOwnProperty.call(event, "isValid") && (event.changed != null)) {
1866
+ _this.okButtonDisabled = !event.isValid;
1958
1867
  }
1959
1868
  });
1960
1869
  }
1961
- if (this.target) {
1962
- var target = this.target;
1870
+ };
1871
+ AdvancedRowActionComponent.prototype.ngOnDestroy = function () {
1872
+ if (this.refreshSubscription) {
1873
+ this.refreshSubscription.unsubscribe();
1874
+ }
1875
+ if (this.executeSubscription) {
1876
+ this.executeSubscription.unsubscribe();
1877
+ }
1878
+ if (this.invalidSubscription) {
1879
+ this.invalidSubscription.unsubscribe();
1963
1880
  }
1964
1881
  };
1965
- AddItemsComponent.prototype.cancel = function () {
1966
- this.clearMessages();
1882
+ AdvancedRowActionComponent.prototype.cancel = function () {
1967
1883
  if (this.loading) {
1968
1884
  return;
1969
1885
  }
@@ -1972,928 +1888,540 @@ var AddItemsComponent = /** @class */ (function (_super) {
1972
1888
  return this._modalService.modalRef.hide();
1973
1889
  }
1974
1890
  };
1975
- AddItemsComponent.prototype.ngOnDestroy = function () {
1976
- if (this.formLoadSubscription) {
1977
- this.formLoadSubscription.unsubscribe();
1978
- }
1979
- if (this.formChangeSubscription) {
1980
- this.formChangeSubscription.unsubscribe();
1981
- }
1982
- if (this.selectedSubscription) {
1983
- this.selectedSubscription.unsubscribe();
1984
- }
1985
- };
1986
- Object.defineProperty(AddItemsComponent.prototype, "formData", {
1987
- get: function () {
1988
- if (this.formComponent === null) {
1989
- return null;
1990
- }
1991
- return this.formComponent.form.formio.data;
1992
- },
1993
- enumerable: true,
1994
- configurable: true
1995
- });
1996
- AddItemsComponent.prototype.ok = function () {
1997
- var _this = this;
1998
- try {
1999
- this.clearMessages();
2000
- return new Promise(function (resolve, reject) {
2001
- _this.loading = false;
2002
- _this.lastError = null;
2003
- // set courses
2004
- _this.items = _this.selectComponent.advancedTable.selected;
2005
- // execute add
2006
- _this.executeSubscription = _this.execute.subscribe(function (result) {
2007
- _this.loading = false;
2008
- if (_this.executeSubscription) {
2009
- _this.executeSubscription.unsubscribe();
2010
- }
2011
- // close modal
2012
- if (_this._modalService.modalRef) {
2013
- _this._modalService.modalRef.hide();
1891
+ AdvancedRowActionComponent.prototype.ok = function () {
1892
+ return __awaiter(this, void 0, void 0, function () {
1893
+ var _this = this;
1894
+ return __generator(this, function (_a) {
1895
+ try {
1896
+ this.loading = true;
1897
+ this.lastError = null;
1898
+ if (this.formComponent && this.formComponent.form &&
1899
+ this.formComponent.form.formio && this.formComponent.form.formio.data) {
1900
+ // set data
1901
+ this.data = this.formComponent.form.formio.data;
2014
1902
  }
2015
- return resolve();
2016
- }, function (err) {
2017
- _this.loading = false;
2018
- // ensure that loading is hidden
2019
- _this._loadingService.hideLoading();
2020
- // set last error
2021
- _this.lastError = err;
2022
- return resolve();
2023
- });
1903
+ // do action
1904
+ this.execute.subscribe(function (result) {
1905
+ _this.loading = false;
1906
+ _this.refresh.emit({
1907
+ progress: 100
1908
+ });
1909
+ if (result && result.errors && result.errors > 0) {
1910
+ // show message for partial success
1911
+ if (result.errors === 1) {
1912
+ _this.lastError = new Error(_this._translateService.instant(_this.errorMessage + ".Description.One"));
1913
+ }
1914
+ else {
1915
+ _this.lastError = new Error(_this._translateService.instant(_this.errorMessage + ".Description.Many", result));
1916
+ }
1917
+ _this.refresh.emit({
1918
+ progress: 1
1919
+ });
1920
+ _this.hideProgress();
1921
+ return;
1922
+ }
1923
+ if (_this._modalService.modalRef) {
1924
+ _this._modalService.modalRef.hide();
1925
+ }
1926
+ }, function (err) {
1927
+ _this.loading = false;
1928
+ _this.lastError = err;
1929
+ _this.refresh.emit({
1930
+ progress: 0
1931
+ });
1932
+ });
1933
+ }
1934
+ catch (err) {
1935
+ this.loading = false;
1936
+ this.lastError = err;
1937
+ }
1938
+ return [2 /*return*/];
2024
1939
  });
2025
- }
2026
- catch (err) {
2027
- this.loading = false;
2028
- this._loadingService.hideLoading();
2029
- this.lastError = err;
2030
- }
1940
+ });
2031
1941
  };
2032
- AddItemsComponent.prototype.onChange = function ($event) { };
2033
- AddItemsComponent.prototype.clearMessages = function () {
2034
- this.messages = [];
1942
+ AdvancedRowActionComponent.prototype.showProgress = function () {
1943
+ this.progressContainer.nativeElement.classList.replace('invisible', 'visible');
2035
1944
  };
2036
- AddItemsComponent.prototype.onFilterChange = function (event) { };
2037
- AddItemsComponent.decorators = [
1945
+ AdvancedRowActionComponent.prototype.hideProgress = function () {
1946
+ this.progressContainer.nativeElement.classList.replace('visible', 'invisible');
1947
+ };
1948
+ AdvancedRowActionComponent.decorators = [
2038
1949
  { type: Component, args: [{
2039
- selector: 'app-add-items',
2040
- template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"alert alert-danger col-12\" role=\"alert\">\n <span [translate]=\"'E' + (lastError.statusCode || 500) + '.title'\"></span><br>\n <small *ngIf=\"lastError.statusCode >= 0\" [translate]=\"'E' + (lastError.statusCode || 500) + '.message'\"></small>\n <small *ngIf=\"lastError.statusCode == null\">{{lastError.message}}</small>\n </div>\n </div>\n <div class=\"row d-none\" *ngIf=\"items\">\n <div class=\"col-12\">\n <p [translate]=\"'StudyPrograms.AddCoursesHelp'\" [translateParams]=\"items\" ></p>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col-12\">\n <ng-container>\n <ul style=\"margin-left: -24px\" class=\"nav nav-tabs mb-1\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\" *ngIf=\"tableConfiguration\">\n <a class=\"nav-link active\" id=\"courses-tab\" data-toggle=\"tab\" href=\"#courses\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\" [translate]=\"'AddItems.SelectCourses'\" ></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"formName\">\n <a class=\"nav-link\" [ngClass]=\"{ 'disabled': !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) }\" id=\"attributes-tab\" data-toggle=\"tab\" href=\"#attributes\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.EditAttributes'\"></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"messages && messages.length > 0\">\n <a class=\"nav-link\" id=\"messages-tab\" data-toggle=\"tab\" href=\"#messages\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.Messages'\"></a>\n </li>\n </ul>\n <div class=\"tab-content border-0\" id=\"myTabContent\">\n <div class=\"tab-pane fade show active\" id=\"courses\" role=\"tabpanel\" aria-labelledby=\"home-tab\">\n <app-advanced-table-modal #selectComponent (filter)=\"onFilterChange($event)\" [tableConfig]=\"tableConfiguration\"></app-advanced-table-modal>\n </div>\n <div class=\"tab-pane fade\" id=\"attributes\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(formName == null)}\">\n<!-- <advanced-form-edit #formComponent [formName]=\"formName\" ></advanced-form-edit>-->\n </div>\n <div class=\"tab-pane fade\" id=\"messages\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(messages == null)}\">\n <ul *ngIf=\"messages && messages.length>0\" class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center\">\n <div class=\"sis--list-group-item_lg_column\" [translate]=\"'AddItems.Messages'\"></div>\n </div>\n </li>\n </ul>\n <ul class=\"sis--list-group sis--list-group-body\">\n <li *ngFor=\"let message of messages\" class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <div class=\"sis--list-group-item_lg_column\">{{ message?.message }}</div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"messages && messages.length>0\">\n <button [disabled]=\"loading\" (click)=\"clearMessages()\" type=\"button\" class=\"btn btn-indigo mt-3\">\n {{'Clear' | translate}}\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) \" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{'OK' | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{'Cancel' | translate}}\n </button>\n </div>\n</div>\n"
1950
+ selector: 'app-advanced-row-action',
1951
+ template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0 mt-2 pb-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"col-12\">\n <div class=\"alert alert-warning\" role=\"alert\">\n <span>{{ 'Tables.Actions.CompletedWithErrors.Title' | translate }}</span><br>\n <small *ngIf=\"lastError.status >= 0\" [translate]=\"'E' + lastError.status + '.message'\"></small>\n <small *ngIf=\"lastError.status == null\">{{lastError.message}}</small>\n </div>\n </div>\n </div>\n <div class=\"row\" *ngIf=\"description\">\n <div class=\"col-12 mb-3\">\n <div class=\"text-justify\">\n {{description | translate}}\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <div *ngIf=\"items && items.length > 1\" [translate]=\"'Tables.Actions.ActionMessage.Many'\" [translateParams]=\"items\"></div>\n <div *ngIf=\"items && items.length === 1\" [translate]=\"'Tables.Actions.ActionMessage.One'\"></div>\n <div class=\"font-weight-bold text-danger\" *ngIf=\"items && items.length <= 0\" [translate]=\"'Tables.Actions.ActionMessage.None'\"></div>\n <div class=\"pt-2 font-weight-bold text-danger\" *ngIf=\"additionalMessage && items && items.length <= 0\">{{additionalMessage}}</div>\n </div>\n </div>\n <div class=\"row pt-3\" *ngIf=\"formTemplate\">\n <div class=\"col-12 mb-3\">\n <div>\n <advanced-form-edit #formComponent [formName]=\"formTemplate\" [(data)]=\"data\"></advanced-form-edit>\n </div>\n </div>\n </div>\n\n <div class=\"row mt-3\">\n <div class=\"col-12 invisible\" #progressContainer>\n <progressbar #progress [type]=\"progressType\" [max]=\"100\">\n </progressbar>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || (items && items.length === 0)\" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{okButtonText | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{cancelButtonText | translate}}\n </button>\n </div>\n</div>\n",
1952
+ encapsulation: ViewEncapsulation.None,
1953
+ styles: ["\n .fa-1_5x {\n font-size: 1.5rem;\n }\n .form-control:disabled, .form-control[readonly] {\n background-color: inherit;\n }\n .form-check.checkbox {\n position: relative\n }\n "]
2041
1954
  }] }
2042
1955
  ];
2043
1956
  /** @nocollapse */
2044
- AddItemsComponent.ctorParameters = function () { return [
1957
+ AdvancedRowActionComponent.ctorParameters = function () { return [
2045
1958
  { type: Router },
2046
1959
  { type: ActivatedRoute },
1960
+ { type: TranslateService },
1961
+ { type: AngularDataContext },
2047
1962
  { type: ErrorService },
2048
1963
  { type: ModalService },
2049
- { type: AppEventService },
2050
- { type: ToastService },
2051
- { type: LoadingService },
2052
- { type: TranslateService },
2053
- { type: AngularDataContext }
1964
+ { type: AppEventService }
2054
1965
  ]; };
2055
- AddItemsComponent.propDecorators = {
2056
- execute: [{ type: Input }],
1966
+ AdvancedRowActionComponent.propDecorators = {
2057
1967
  items: [{ type: Input }],
2058
- target: [{ type: Input }],
2059
- tableConfiguration: [{ type: Input }],
2060
- formName: [{ type: Input }],
2061
- messages: [{ type: Input }],
1968
+ modalIcon: [{ type: Input }],
1969
+ description: [{ type: Input }],
1970
+ formTemplate: [{ type: Input }],
1971
+ progressType: [{ type: Input }],
1972
+ data: [{ type: Output }],
1973
+ additionalMessage: [{ type: Input }],
1974
+ errorMessage: [{ type: Input }],
1975
+ progressComponent: [{ type: ViewChild, args: ['progress',] }],
1976
+ progressContainer: [{ type: ViewChild, args: ['progressContainer',] }],
2062
1977
  formComponent: [{ type: ViewChild, args: ['formComponent',] }],
2063
- selectComponent: [{ type: ViewChild, args: ['selectComponent',] }]
1978
+ refresh: [{ type: Input }],
1979
+ execute: [{ type: Input }]
2064
1980
  };
2065
- return AddItemsComponent;
1981
+ return AdvancedRowActionComponent;
2066
1982
  }(RouterModalOkCancel));
2067
1983
 
2068
- var AdvancedAggregatorService = /** @class */ (function () {
2069
- function AdvancedAggregatorService(_context, _template) {
2070
- this._context = _context;
2071
- this._template = _template;
1984
+ var AdvancedTableSearchBaseComponent = /** @class */ (function () {
1985
+ function AdvancedTableSearchBaseComponent() {
1986
+ this.filterChange = new EventEmitter();
2072
1987
  }
2073
- /**
2074
- *
2075
- * Formats and executes the data query
2076
- *
2077
- * @param {string} model The target model
2078
- * @param {object} fixedParams Pairs of parameters to always be applied
2079
- * @param {string} queryStatement The default query to use for fetching the data (e.g. expands etc)
2080
- * @param {Array<string>} filters A list of filter expressions to append at the query
2081
- * @param {string} searchTemplate The template to use for searching expressions
2082
- * @param {string} searchValue The value of the user search
2083
- *
2084
- * @returns {Promise<any>} The response of the query execution
2085
- */
2086
- AdvancedAggregatorService.prototype.fetchData = function (model, fixedParams, queryStatement, filters, searchTemplate, searchValue) {
2087
- if (queryStatement === void 0) { queryStatement = ''; }
2088
- return __awaiter(this, void 0, void 0, function () {
2089
- var e_1, _a, query, filterExpressions, _b, _c, param, evaluatedSearch, words;
2090
- var _this = this;
2091
- return __generator(this, function (_d) {
2092
- query = this._context.model(model).asQueryable();
2093
- if (!fixedParams || typeof fixedParams !== 'object') {
2094
- fixedParams = {};
2095
- }
2096
- filterExpressions = [];
2097
- if (fixedParams) {
2098
- try {
2099
- for (_b = __values(Object.keys(fixedParams)), _c = _b.next(); !_c.done; _c = _b.next()) {
2100
- param = _c.value;
2101
- filterExpressions.push(param + " eq " + fixedParams[param]);
2102
- }
2103
- }
2104
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2105
- finally {
2106
- try {
2107
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2108
- }
2109
- finally { if (e_1) throw e_1.error; }
2110
- }
2111
- }
2112
- if (filters && Array.isArray(filters)) {
2113
- filterExpressions = __spread(filterExpressions, filters);
2114
- }
2115
- if (searchTemplate && searchValue) {
2116
- evaluatedSearch = void 0;
2117
- if (/^"(.*?)"$/.test(searchValue)) { // validate search text in double quotes
2118
- evaluatedSearch = this._template.transform(searchTemplate, __assign({}, fixedParams, { text: searchValue.replace(/^"|"$/g, '') }));
2119
- }
2120
- else {
2121
- words = searchValue.split(' ');
2122
- // join words to a single filter
2123
- evaluatedSearch = words.map(function (word) {
2124
- return _this._template.transform(searchTemplate, __assign({}, fixedParams, { text: word }));
2125
- }).join(' and ');
2126
- }
2127
- filterExpressions.push(evaluatedSearch);
2128
- }
2129
- query.setParam('$filter', filterExpressions.join('and'));
2130
- return [2 /*return*/, query.expand(queryStatement).take(-1).getItems()];
2131
- });
2132
- });
1988
+ Object.defineProperty(AdvancedTableSearchBaseComponent.prototype, "filter", {
1989
+ get: function () {
1990
+ return this._filter;
1991
+ },
1992
+ set: function (value) {
1993
+ this._filter = value;
1994
+ },
1995
+ enumerable: true,
1996
+ configurable: true
1997
+ });
1998
+ AdvancedTableSearchBaseComponent.prototype.onKeyEnter = function (event) {
1999
+ if (event.code === 'Enter') {
2000
+ this.filterChange.emit(this._filter);
2001
+ }
2133
2002
  };
2134
- /**
2135
- *
2136
- * Formats the received data to use flat keys
2137
- *
2138
- * @param config The applied configuration
2139
- * @param data The raw data
2140
- *
2141
- * @returns {Array<any>} The flat-key object list
2142
- *
2143
- */
2144
- AdvancedAggregatorService.prototype.formatData = function (config, data) {
2003
+ AdvancedTableSearchBaseComponent.propDecorators = {
2004
+ filterChange: [{ type: Output }],
2005
+ filter: [{ type: Input }]
2006
+ };
2007
+ return AdvancedTableSearchBaseComponent;
2008
+ }());
2009
+
2010
+ var AdvancedSearchFormComponent = /** @class */ (function (_super) {
2011
+ __extends(AdvancedSearchFormComponent, _super);
2012
+ function AdvancedSearchFormComponent(_context, _translateService, _activatedRoute, _http) {
2013
+ var _this = _super.call(this) || this;
2014
+ _this._context = _context;
2015
+ _this._translateService = _translateService;
2016
+ _this._activatedRoute = _activatedRoute;
2017
+ _this._http = _http;
2018
+ _this.form = {};
2019
+ _this.refreshForm = new EventEmitter();
2020
+ _this.submission = { data: {} };
2021
+ _this.loading = true;
2022
+ return _this;
2023
+ }
2024
+ AdvancedSearchFormComponent.prototype.ngOnChanges = function (changes) {
2145
2025
  var _this = this;
2146
- try {
2147
- return data.map(function (entry) {
2148
- if (entry.subitems && Array.isArray(entry.subitems)) {
2149
- entry.subitems = _this.formatData(config, entry.subitems);
2026
+ if (Object.prototype.hasOwnProperty.call(changes, 'form')) {
2027
+ if (changes.form != null) {
2028
+ if (changes.form.currentValue &&
2029
+ changes.form.currentValue != changes.form.previousValue) {
2030
+ this.ngOnInit();
2150
2031
  }
2151
- var entryObject = {};
2152
- for (var i = 0; i < config.columns.length; i++) {
2153
- var keys = config.columns[i].name.split('/');
2154
- var helperObject = entry[keys[0]];
2155
- if (helperObject && keys.length > 1) {
2156
- for (var i_1 = 1; i_1 < keys.length; i_1++) {
2157
- if (helperObject === undefined || helperObject === null) {
2158
- break;
2159
- }
2160
- else {
2161
- helperObject = helperObject[keys[i_1]] !== undefined && helperObject[keys[i_1]] !== null
2162
- ? helperObject[keys[i_1]]
2163
- : undefined;
2164
- }
2165
- }
2166
- }
2167
- entryObject[config.columns[i].name] = helperObject;
2168
- }
2169
- if (entry.subitems) {
2170
- entryObject.subitems = entry.subitems;
2032
+ }
2033
+ }
2034
+ if (Object.prototype.hasOwnProperty.call(changes, 'formSrc')) {
2035
+ if (changes.formSrc != null) {
2036
+ if (changes.formSrc.currentValue &&
2037
+ changes.formSrc.currentValue != changes.formSrc.previousValue) {
2038
+ this._http.get(changes.formSrc.currentValue).toPromise().then(function (form) {
2039
+ // set form
2040
+ _this.form = form;
2041
+ // and init
2042
+ _this.ngOnInit();
2043
+ }).catch(function (err) {
2044
+ console.error('An error occurred while loading search configuration');
2045
+ console.error(err);
2046
+ });
2171
2047
  }
2172
- return entryObject;
2173
- });
2048
+ }
2174
2049
  }
2175
- catch (err) {
2176
- console.error(err);
2050
+ if (Object.prototype.hasOwnProperty.call(changes, 'filter')) {
2051
+ if (changes.filter != null) {
2052
+ this.submission.data = changes.filter.currentValue || {};
2053
+ this.refreshForm.emit({
2054
+ submission: this.submission
2055
+ });
2056
+ }
2177
2057
  }
2178
2058
  };
2179
- AdvancedAggregatorService.decorators = [
2180
- { type: Injectable, args: [{
2181
- providedIn: 'root'
2182
- },] }
2183
- ];
2184
- /** @nocollapse */
2185
- AdvancedAggregatorService.ctorParameters = function () { return [
2186
- { type: AngularDataContext },
2187
- { type: TemplatePipe }
2188
- ]; };
2189
- AdvancedAggregatorService.ngInjectableDef = defineInjectable({ factory: function AdvancedAggregatorService_Factory() { return new AdvancedAggregatorService(inject(AngularDataContext), inject(TemplatePipe)); }, token: AdvancedAggregatorService, providedIn: "root" });
2190
- return AdvancedAggregatorService;
2191
- }());
2192
-
2193
- /**
2194
- *
2195
- * @class AdvancedAggregatorComponent
2196
- * @classdesc An advanced list with the capability of aggregate data based on configurable filters
2197
- *
2198
- */
2199
- var AdvancedAggregatorComponent = /** @class */ (function () {
2200
- function AdvancedAggregatorComponent(_changeDetector, _advancedAggregatorService, _loadingService) {
2201
- this._changeDetector = _changeDetector;
2202
- this._advancedAggregatorService = _advancedAggregatorService;
2203
- this._loadingService = _loadingService;
2204
- this.groups = [];
2205
- this.eventHandler = new EventEmitter();
2206
- }
2207
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "config", {
2208
- get: function () {
2209
- return this._config;
2210
- },
2211
- set: function (value) {
2212
- this._config = value;
2213
- },
2214
- enumerable: true,
2215
- configurable: true
2216
- });
2217
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "aggregators", {
2218
- get: function () {
2219
- return this._aggregators;
2220
- },
2221
- set: function (value) {
2222
- this._aggregators = value;
2223
- },
2224
- enumerable: true,
2225
- configurable: true
2226
- });
2227
- Object.defineProperty(AdvancedAggregatorComponent.prototype, "postProcessors", {
2228
- get: function () {
2229
- return this._postProcessors;
2230
- },
2231
- set: function (value) {
2232
- this._postProcessors = value;
2233
- },
2234
- enumerable: true,
2235
- configurable: true
2236
- });
2237
- AdvancedAggregatorComponent.prototype.ngOnInit = function () {
2238
- return __awaiter(this, void 0, void 0, function () {
2239
- var _this = this;
2240
- return __generator(this, function (_a) {
2241
- this.selectedGroups$.subscribe(function (data) {
2242
- _this.groups = data;
2243
- _this._changeDetector.markForCheck();
2244
- });
2245
- this.filters$.subscribe(function (filters) { return __awaiter(_this, void 0, void 0, function () {
2246
- var err_1;
2247
- return __generator(this, function (_a) {
2248
- switch (_a.label) {
2249
- case 0:
2250
- _a.trys.push([0, 2, , 3]);
2251
- return [4 /*yield*/, this.fetch(filters)];
2252
- case 1:
2253
- _a.sent();
2254
- return [3 /*break*/, 3];
2255
- case 2:
2256
- err_1 = _a.sent();
2257
- console.error(err_1);
2258
- return [3 /*break*/, 3];
2259
- case 3: return [2 /*return*/];
2260
- }
2261
- });
2262
- }); });
2263
- return [2 /*return*/];
2059
+ AdvancedSearchFormComponent.prototype.ngOnInit = function () {
2060
+ var _this = this;
2061
+ if (this.form) {
2062
+ new ServiceUrlPreProcessor(this._context).parse(this.form);
2063
+ new TranslatePreProcessor(this._translateService).parse(this.form);
2064
+ this.submission = {
2065
+ data: this.filter
2066
+ };
2067
+ this.refreshForm.emit({
2068
+ form: this.form
2264
2069
  });
2265
- });
2266
- };
2267
- AdvancedAggregatorComponent.prototype.ngOnDestroy = function () {
2268
- return __awaiter(this, void 0, void 0, function () {
2269
- return __generator(this, function (_a) {
2270
- this.selectedGroups$.unsubscribe();
2271
- this.filters$.unsubscribe();
2272
- return [2 /*return*/];
2070
+ this.loading = false;
2071
+ this.filterSubscription = this.filterChange.subscribe(function (filter) {
2072
+ _this.submission.data = filter;
2073
+ _this.refreshForm.emit({
2074
+ submission: _this.submission
2075
+ });
2273
2076
  });
2274
- });
2077
+ }
2275
2078
  };
2276
- /**
2277
- *
2278
- * Retrieves the data
2279
- *
2280
- */
2281
- AdvancedAggregatorComponent.prototype.fetch = function (filters) {
2282
- return __awaiter(this, void 0, void 0, function () {
2283
- var data, i, err_2;
2284
- return __generator(this, function (_a) {
2285
- switch (_a.label) {
2286
- case 0:
2287
- _a.trys.push([0, 6, 7, 8]);
2288
- this._loadingService.showLoading();
2289
- return [4 /*yield*/, this._advancedAggregatorService.fetchData(this.config.model, this.params, this.config.query, filters.filters, this.searchExpression, filters.text)];
2290
- case 1:
2291
- data = _a.sent();
2292
- if (!(this.postProcessors && Object.keys(this.postProcessors).length > 0 && this.config.postProcessors && this.config.postProcessors.length > 0)) return [3 /*break*/, 5];
2293
- i = 0;
2294
- _a.label = 2;
2295
- case 2:
2296
- if (!(i < this.config.postProcessors.length)) return [3 /*break*/, 5];
2297
- return [4 /*yield*/, this.postProcessors[this.config.postProcessors[i].name](data)];
2298
- case 3:
2299
- data = _a.sent();
2300
- _a.label = 4;
2301
- case 4:
2302
- i++;
2303
- return [3 /*break*/, 2];
2304
- case 5:
2305
- this.body = this._advancedAggregatorService.formatData(this.config, data);
2306
- this._changeDetector.markForCheck();
2307
- return [3 /*break*/, 8];
2308
- case 6:
2309
- err_2 = _a.sent();
2310
- console.error(err_2);
2311
- return [3 /*break*/, 8];
2312
- case 7:
2313
- this._loadingService.hideLoading();
2314
- return [7 /*endfinally*/];
2315
- case 8: return [2 /*return*/];
2079
+ AdvancedSearchFormComponent.prototype.onChange = function (event) {
2080
+ var _this = this;
2081
+ Object.keys(this.formComponent.submission.data).forEach(function (key) {
2082
+ if (Object.prototype.hasOwnProperty.call(_this.formComponent.submission.data, key)) {
2083
+ var value = _this.formComponent.submission.data[key];
2084
+ // the filter with type is a string and is not empty
2085
+ var isEmptyString = typeof value === 'string' && value.length === 0;
2086
+ if (!isEmptyString) {
2087
+ Object.defineProperty(_this.filter, key, {
2088
+ configurable: true,
2089
+ enumerable: true,
2090
+ value: value
2091
+ });
2316
2092
  }
2317
- });
2093
+ else {
2094
+ delete _this.filter[key];
2095
+ }
2096
+ }
2318
2097
  });
2319
2098
  };
2320
- /**
2321
- *
2322
- * Triggers the event handler event
2323
- *
2324
- * @param {*} event The event data
2325
- *
2326
- */
2327
- AdvancedAggregatorComponent.prototype.onActionEvent = function (event) {
2328
- this.eventHandler.emit(event);
2099
+ AdvancedSearchFormComponent.prototype.onFormLoad = function (form) {
2100
+ var currentLang = this._translateService.currentLang;
2101
+ this.formComponent.formio.i18next.options.resources[currentLang] = { translation: this._translateService.instant("Forms") };
2102
+ this.formComponent.formio.language = currentLang;
2329
2103
  };
2330
- AdvancedAggregatorComponent.decorators = [
2104
+ AdvancedSearchFormComponent.prototype.ngAfterViewInit = function () {
2105
+ //
2106
+ };
2107
+ AdvancedSearchFormComponent.prototype.ngOnDestroy = function () {
2108
+ if (this.filterSubscription) {
2109
+ this.filterSubscription.unsubscribe();
2110
+ }
2111
+ };
2112
+ AdvancedSearchFormComponent.decorators = [
2331
2113
  { type: Component, args: [{
2332
- selector: 'app-advanced-aggregator',
2333
- template: "<ng-container *ngIf=\"config && body\">\n <div class=\"w-100 text-center\" *ngIf=\"body && body.length === 0\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"groups.length === 0\">\n <div class=\"row mt-4\">\n <app-advanced-aggregator-list [body]=\"body\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\" class=\"col-12\">\n </app-advanced-aggregator-list>\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ body | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"groups.length === 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <app-advanced-aggregator-list [body]=\"group.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for the group -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ group.value | callAggregator: aggregators: aggregator.name }} </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"groups.length > 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <div *ngFor=\"let subgroup of group.value | groupBy: groups[1].name | keyvalue\" class=\"col-12 ml-4 pl-4\">\n <div class=\"row mt-4\">\n <h6 class=\"col-12 text-secondary\"> {{ groups[1].title | aggregatorListTitle: subgroup.key }} </h6>\n <app-advanced-aggregator-list [body]=\"subgroup.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for each subgroup -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ subgroup.value | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</ng-container>",
2334
- changeDetection: ChangeDetectionStrategy.OnPush
2114
+ selector: 'app-advanced-search-form',
2115
+ template: "\n <div class=\"p-4\">\n <formio #formioComponent class=\"formio-search\" (keydown)=\"onKeyEnter($event)\" (change)=\"onChange($event)\" (formLoad)=\"onFormLoad($event)\"\n [refresh]=\"refreshForm\" [submission]=\"submission\" [form]=\"form\"></formio>\n </div>\n ",
2116
+ encapsulation: ViewEncapsulation.None,
2117
+ styles: ["formio.formio-search .form-group{margin-bottom:0}formio.formio-search .form-group .col-form-label{font-size:90%;padding-top:4px;padding-bottom:4px}.choices__list.choices__list--single .choices__item:first-child.choices__item--selectable{width:85%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}"]
2335
2118
  }] }
2336
2119
  ];
2337
2120
  /** @nocollapse */
2338
- AdvancedAggregatorComponent.ctorParameters = function () { return [
2339
- { type: ChangeDetectorRef },
2340
- { type: AdvancedAggregatorService },
2341
- { type: LoadingService }
2121
+ AdvancedSearchFormComponent.ctorParameters = function () { return [
2122
+ { type: AngularDataContext },
2123
+ { type: TranslateService },
2124
+ { type: ActivatedRoute },
2125
+ { type: HttpClient }
2342
2126
  ]; };
2343
- AdvancedAggregatorComponent.propDecorators = {
2344
- config: [{ type: Input, args: ['config',] }],
2345
- aggregators: [{ type: Input, args: ['aggregators',] }],
2346
- postProcessors: [{ type: Input, args: ['postProcessors',] }],
2347
- params: [{ type: Input, args: ['params',] }],
2348
- selectedGroups$: [{ type: Input, args: ['selectedGroups',] }],
2349
- filters$: [{ type: Input, args: ['filters',] }],
2350
- searchExpression: [{ type: Input, args: ['searchExpression',] }],
2351
- eventHandler: [{ type: Output }]
2127
+ AdvancedSearchFormComponent.propDecorators = {
2128
+ formComponent: [{ type: ViewChild, args: ['formioComponent',] }],
2129
+ form: [{ type: Input }],
2130
+ formSrc: [{ type: Input }],
2131
+ refreshForm: [{ type: Output }]
2352
2132
  };
2353
- return AdvancedAggregatorComponent;
2354
- }());
2133
+ return AdvancedSearchFormComponent;
2134
+ }(AdvancedTableSearchBaseComponent));
2355
2135
 
2356
- var Lengths;
2357
- (function (Lengths) {
2358
- Lengths["XL"] = "xl";
2359
- Lengths["LG"] = "lg";
2360
- Lengths["MD"] = "md";
2361
- Lengths["SM"] = "sm";
2362
- Lengths["XS"] = "xs";
2363
- })(Lengths || (Lengths = {}));
2364
- var AdvancedAggregatorListComponent = /** @class */ (function () {
2365
- function AdvancedAggregatorListComponent(_template) {
2366
- this._template = _template;
2367
- this.clickEvent = new EventEmitter();
2136
+ // important: export this const due to AOT compilation errors
2137
+ // see more https://angular.io/guide/aot-metadata-errors#only-initialized-variables
2138
+ var AdvancedTableModalBaseTemplate = "\n<div>\n <!-- search -->\n <div class=\"row mt-3\">\n <div class=\"col-12 col-lg-3\">\n <div class=\"input-group mb-3\">\n <input spellcheck=\"false\" type=\"text\"\n (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"searchText\"\n class=\"form-control bg-gray-100 border-0\"\n placeholder=\"{{'Tables.SearchPlaceholder' | translate}}\" aria-label=\"Search\" aria-describedby=\"basic-addon2\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-default bg-gray-100 border-0\" type=\"button\">\n <i class=\"fa fa-search text-secondary\"></i>\n </button>\n </div>\n </div>\n </div>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n\n </div>\n </div>\n <div class=\"col-12 col-lg-5\">\n <div class=\"btn-toolbar\">\n <button class=\"btn btn-gray-100\">\n <i class=\"fa fa-sliders-h pr-2 text-secondary\" aria-hidden=\"true\"></i>{{'Tables.Filters' | translate}}\n </button>\n <div #dropdownFilter class=\"dropdown ml-3\">\n <button class=\"btn btn-gray-100 dropdown-toggle\"\n type=\"button\" id=\"dropdownDefaultFilters\"\n data-toggle=\"dropdown\" dropdownToggle>\n {{ this.defaultFilter.name | translate }}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownDefaultFilters\">\n <button type=\"button\" class=\"dropdown-item\" *ngFor=\"let filter of defaultFilters\" (click)=\"onFilterSelect(filter)\">\n {{ filter.name | translate }}\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col text-lg-right mt-3 mt-lg-0 d-none\">\n <button [disabled]=\"true\" class=\"btn rounded-pill btn-outline-theme\">\n <span class=\"pr-2 font-lg\">+</span><span [translate]=\"'Tables.AddItem'\"></span>\n </button>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\" [ngClass]=\"{ 'component-loading': loading}\">\n <app-advanced-table #advancedTable (init)=\"onTableInit($event)\"\n (load)=\"onDataLoad($event)\"\n [selectable]=\"true\"\n [multipleSelect]=\"true\"\n [scrollX]=\"false\" [scrollY]=\"320\"\n [pageLength]=\"pageLength\"\n [scrollable]=\"false\" [showFooter]=\"false\"\n [showActions]=\"false\" [lengthMenu]=\"lengthMenu\"\n [config]=\"tableConfig\" [configSrc]=\"tableConfigSrc\"></app-advanced-table>\n </div>\n </div>\n <div class=\"row mt-3 table-custom-pager\">\n <div class=\"col-12 d-flex\" *ngIf=\"recordsTotal\">\n <div class=\"mt-2 ml-auto mr-3 text-secondary\" [translate]=\"'Tables.RecordsPerPage'\"></div>\n <div #dropdownLength class=\"dropdown mr-3\">\n <button class=\"btn btn-gray-100 dropdown-toggle\"\n type=\"button\" id=\"dropdownPageSize\" data-toggle=\"dropdown\"\n dropdownToggle>\n {{pageLength}}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownPageSize\">\n <button (click)=\"setLength(item)\"\n class=\"dropdown-item dropdown-item-theme\"\n type=\"button\" *ngFor=\"let item of lengthMenu\">{{item}}</button>\n </div>\n </div>\n <div class=\"mt-2 mr-2\" [translate]=\"'Tables.PageInfo'\" [translateParams]=\"pageInfo\"></div>\n <button [disabled]=\"pageInfo && pageInfo.page === 0\" class=\"btn text-nowrap\" (click)=\"firstPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===0\" class=\"btn\" (click)=\"previousPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn\" (click)=\"nextPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn text-nowrap\" (click)=\"lastPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n </div>\n </div>\n </div>\n";
2139
+ var AdvancedTableModalBaseComponent = /** @class */ (function (_super) {
2140
+ __extends(AdvancedTableModalBaseComponent, _super);
2141
+ function AdvancedTableModalBaseComponent(_router, _activatedRoute, _context, advancedFilterValueProvider, datePipe) {
2142
+ var _this = _super.call(this, _router, _activatedRoute) || this;
2143
+ _this._context = _context;
2144
+ _this.advancedFilterValueProvider = advancedFilterValueProvider;
2145
+ _this.datePipe = datePipe;
2146
+ _this.pageLength = 25;
2147
+ _this.lengthMenu = [5, 10, 25, 50, 100];
2148
+ _this.recordsTotal = 0;
2149
+ _this.loading = false;
2150
+ _this.recordsFiltered = 0;
2151
+ _this.defaultFilters = [AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER];
2152
+ _this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
2153
+ _this.pageInfo = {
2154
+ serverSide: true
2155
+ };
2156
+ _this.modalClass = 'modal-xl modal-table';
2157
+ _this._template = new TemplatePipe();
2158
+ return _this;
2368
2159
  }
2369
- AdvancedAggregatorListComponent.prototype.ngOnInit = function () {
2370
- var _this = this;
2371
- this.config.columns.forEach(function (x) {
2372
- x.length = Object.values(Lengths).includes(x.length) ? _this._template.transform("sis--list-group-item_" + x.length + "_column", x) :
2373
- !x.length ? 'sis--list-group-item_sm_column' : x.length;
2374
- });
2375
- };
2376
- /**
2377
- *
2378
- * Triggers the output event emitter
2379
- *
2380
- * @param type The type of the event as it's declared in the configuration
2381
- * @param item The value of the current item
2382
- * }
2383
- */
2384
- AdvancedAggregatorListComponent.prototype.callCallback = function (type, data) {
2385
- this.clickEvent.emit({
2386
- type: type,
2387
- data: data
2388
- });
2389
- };
2390
- AdvancedAggregatorListComponent.decorators = [
2391
- { type: Component, args: [{
2392
- selector: 'app-advanced-aggregator-list',
2393
- template: "<div id=\"group-list\" class=\"flex-column\" *ngIf=\"config && config.columns\">\n <ul class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item text-wrap\">\n <div class=\"d-flex justify-content-center align-items-center\" *ngIf=\"body && body.length > 0\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column\"></div>\n <div *ngFor=\"let column of config.columns; let i = index\" class=\"text-left\"\n [class]=\"config.columns[i].length\"\n [translate]=\"config.columns[i].type === 'action' ? '' : column.title\" [ngClass]=\"{\n 'd-none': config.columns[i].hidden\n }\"></div>\n </div>\n </li>\n </ul>\n\n <!-- The list of entries -->\n <ul class=\"sis--list-group sis--list-group-body\" *ngIf=\"body && body.length > 0\">\n <li class=\"sis--list-group-item text-wrap\" *ngFor=\"let entry of body | orderBy: config.orderBy\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <!-- The list of actions -->\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, entry)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n\n </div>\n <!-- The list of data -->\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && entry[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !entry[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length <= 3\n }\">\n {{entry[column.name] || '-'}}\n </span>\n\n <button *ngIf=\"config.columns[i].type === 'action' && config.columns[i].variant === 'edit'\"\n (click)=\"callCallback(config.columns[i].identifier, entry)\"\n [title]=\"(config.columns[i].title ? config.columns[i].title : '') | translate \"\n class=\"btn btn-default px-0 mx-0\">\n <i class=\"fas fa-edit text-indigo\"></i>\n </button>\n\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': entry[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n <div *ngIf=\"entry && entry.subitems\">\n <div *ngFor=\"let subitem of entry.subitems\" class=\"d-flex justify-content-center align-items-center list-color\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, subitem)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n </div>\n <div class=\"text-left\"></div>\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && subitem[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !subitem[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length <= 3\n }\">\n {{subitem[column.name] || '-'}}\n </span>\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': subitem[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n </div>\n </li>\n </ul>\n</div>\n"
2394
- }] }
2395
- ];
2396
- /** @nocollapse */
2397
- AdvancedAggregatorListComponent.ctorParameters = function () { return [
2398
- { type: TemplatePipe }
2399
- ]; };
2400
- AdvancedAggregatorListComponent.propDecorators = {
2401
- config: [{ type: Input }],
2402
- body: [{ type: Input }],
2403
- clickEvent: [{ type: Output }]
2160
+ AdvancedTableModalBaseComponent.prototype.ngAfterViewInit = function () {
2161
+ //
2404
2162
  };
2405
- return AdvancedAggregatorListComponent;
2406
- }());
2407
-
2408
- var AdvancedListComponent = /** @class */ (function () {
2409
- function AdvancedListComponent(_context, _translateService, _activatedRoute, _errorService, _toastService, _modalService, _userActivityService) {
2410
- this._context = _context;
2411
- this._translateService = _translateService;
2412
- this._activatedRoute = _activatedRoute;
2413
- this._errorService = _errorService;
2414
- this._toastService = _toastService;
2415
- this._modalService = _modalService;
2416
- this._userActivityService = _userActivityService;
2417
- this.allowSaveOption = true;
2418
- }
2419
- AdvancedListComponent.prototype.ngOnDestroy = function () {
2420
- if (this.dataSubscription) {
2421
- this.dataSubscription.unsubscribe();
2422
- }
2423
- if (this.reloadSubscription) {
2424
- this.reloadSubscription.unsubscribe();
2425
- }
2426
- if (this.subscription) {
2427
- this.subscription.unsubscribe();
2163
+ AdvancedTableModalBaseComponent.prototype._getInputs = function (componentType) {
2164
+ var props = componentType.__prop__metadata__;
2165
+ var inputs = [];
2166
+ if (props == null) {
2167
+ return inputs;
2428
2168
  }
2429
- };
2430
- AdvancedListComponent.prototype.ngOnInit = function () {
2431
- return __awaiter(this, void 0, void 0, function () {
2432
- var metadata_1, err_1;
2433
- var _this = this;
2434
- return __generator(this, function (_a) {
2435
- switch (_a.label) {
2436
- case 0:
2437
- _a.trys.push([0, 2, , 3]);
2438
- return [4 /*yield*/, this._context.getMetadata()];
2439
- case 1:
2440
- metadata_1 = _a.sent();
2441
- // get route data
2442
- this.dataSubscription = this._activatedRoute.data.subscribe(function (routeData) {
2443
- // get entityType
2444
- var re = new RegExp("^" + routeData.model + "$", 'ig');
2445
- var entitySet = metadata_1.EntityContainer.EntitySet.find(function (x) {
2446
- return re.test(x.Name);
2447
- });
2448
- // if entity type is null
2449
- if (entitySet == null) {
2450
- // navigate to error
2451
- return _this._errorService.navigateToError(new ResponseError('EntitySet Not Found', 404));
2452
- }
2453
- // get entity type
2454
- var entityType = metadata_1.EntityType.find(function (x) {
2455
- return x.Name === entitySet.EntityType;
2456
- });
2457
- if (entityType == null) {
2458
- return _this._errorService.navigateToError(new ResponseError('EntityType Not Found', 404));
2459
- }
2460
- if (routeData.searchConfiguration) {
2461
- if (Object.prototype.hasOwnProperty.call(routeData.searchConfiguration, 'allowSave')) {
2462
- _this.allowSaveOption = routeData.searchConfiguration.allowSave;
2463
- }
2464
- _this.searchConfiguration = routeData.searchConfiguration;
2465
- }
2466
- if (routeData.tableConfiguration) {
2467
- _this.tableConfiguration = routeData.tableConfiguration;
2468
- }
2469
- if (routeData.description) {
2470
- _this.description = _this._translateService.instant(routeData.description);
2471
- }
2472
- if (routeData.longDescription) {
2473
- _this.longDescription = _this._translateService.instant(routeData.longDescription);
2474
- }
2475
- if (routeData.category) {
2476
- _this.category = _this._translateService.instant(routeData.category);
2477
- }
2478
- // clone default configuration
2479
- var defaultConfiguration = AdvancedTableConfiguration.cast(_this.tableConfiguration, true);
2480
- // correct edit button link
2481
- var column = defaultConfiguration.columns.find(function (col) {
2482
- return col.formatter === 'ButtonFormatter' && col.formatString === '(modal:edit)';
2483
- });
2484
- if (column) {
2485
- var url_1 = [];
2486
- _this._activatedRoute.snapshot.pathFromRoot.forEach(function (route) {
2487
- url_1.push.apply(url_1, route.url);
2488
- });
2489
- column.formatString = "#/" + url_1.join('/') + "/(modal:${id}/edit)";
2490
- }
2491
- // create list configuration by assigning list entity set
2492
- _this.table.config = Object.assign({
2493
- model: entitySet.Name
2494
- }, defaultConfiguration);
2495
- // fetch data
2496
- _this.table.fetch(true);
2497
- // do reload by using hidden fragment e.g. /classes#reload
2498
- _this.reloadSubscription = _this._activatedRoute.fragment.subscribe(function (fragment) {
2499
- if (fragment && fragment === 'reload') {
2500
- _this._toastService.show(_this.description, _this._translateService.instant('Settings.OperationCompleted'));
2501
- _this.table.fetch(true);
2502
- }
2503
- });
2504
- // finally add user activity
2505
- _this._userActivityService.setItem({
2506
- category: _this.category,
2507
- description: _this.description,
2508
- url: window.location.hash.substring(1),
2509
- dateCreated: new Date
2510
- });
2511
- });
2512
- return [3 /*break*/, 3];
2513
- case 2:
2514
- err_1 = _a.sent();
2515
- console.error(err_1);
2516
- return [2 /*return*/, this._errorService.showError(err_1)];
2517
- case 3: return [2 /*return*/];
2518
- }
2519
- });
2169
+ Object.keys(props).forEach(function (prop) {
2170
+ var member = props[prop][0];
2171
+ if (member.ngMetadataName === 'Input') {
2172
+ inputs.push(prop);
2173
+ }
2520
2174
  });
2175
+ return inputs.sort();
2521
2176
  };
2522
- /**
2523
- * Data load event handler of advanced table component
2524
- * @param {AdvancedTableDataResult} data
2525
- */
2526
- AdvancedListComponent.prototype.onDataLoad = function (data) {
2527
- this.recordsTotal = data.recordsTotal;
2177
+ AdvancedTableModalBaseComponent.prototype.hasInputs = function () {
2178
+ return [];
2528
2179
  };
2529
- /**
2530
- * Remove selected items
2531
- */
2532
- AdvancedListComponent.prototype.remove = function () {
2180
+ AdvancedTableModalBaseComponent.prototype.ngOnInit = function () {
2533
2181
  var _this = this;
2534
- if (this.table && this.table.selected && this.table.selected.length) {
2535
- // get items to remove
2536
- var items_1 = this.table.selected;
2537
- return this._modalService.showWarningDialog(this._translateService.instant('Tables.RemoveItemsTitle'), this._translateService.instant('Tables.RemoveItemsMessage'), DIALOG_BUTTONS.OkCancel).then(function (result) {
2538
- if (result === 'ok') {
2539
- _this._context.model(_this.table.config.model).remove(items_1).then(function () {
2540
- _this._toastService.show(_this.description + ':' + _this._translateService.instant('Tables.RemoveItemMessage.title'), _this._translateService.instant((items_1.length === 1 ?
2541
- 'Tables.RemoveItemMessage.one' : 'Tables.RemoveItemMessage.many'), { value: items_1.length }));
2542
- _this.table.fetch(true);
2543
- }).catch(function (err) {
2544
- _this._errorService.showError(err, {
2545
- continueLink: '.'
2546
- });
2547
- });
2182
+ this.okButtonText = 'Tables.Apply';
2183
+ this.cancelButtonText = 'Tables.Cancel';
2184
+ // get route data
2185
+ this.subscription = this.activatedRoute.data.subscribe(function (data) {
2186
+ // set modal title if any
2187
+ if (data.title) {
2188
+ _this.modalTitle = data.title;
2189
+ }
2190
+ if (data.config) {
2191
+ _this.tableConfig = data.config;
2192
+ }
2193
+ if (_this.tableConfig) {
2194
+ _this.defaultFilters.push.apply(_this.defaultFilters, _this.tableConfig.searches);
2195
+ }
2196
+ // important: use hasInputs due to AOT compilation. Metadata properties cannot be used (e.g. @Input())
2197
+ // because there are empty during runtime
2198
+ // so we need to define manually input properties that are going to be bind through this process
2199
+ // bind all inputs
2200
+ var inputs = _this.hasInputs();
2201
+ inputs.forEach(function (input) {
2202
+ if (Object.prototype.hasOwnProperty.call(data, input)) {
2203
+ _this[input] = data[input];
2548
2204
  }
2549
2205
  });
2550
- }
2551
- };
2552
- AdvancedListComponent.decorators = [
2553
- { type: Component, args: [{
2554
- selector: 'app-advanced-list',
2555
- template: "<div>\n <div class=\"row\" *ngIf=\"description\">\n <div class=\"col-auto\">\n <h2>{{description}}</h2>\n <p *ngIf=\"longDescription\">{{longDescription}}</p>\n </div>\n </div>\n <div class=\"row\" *ngIf=\"searchConfiguration\">\n <div class=\"col-12\" [ngVar]=\"{}\" #filter=\"ngVar\">\n <app-advanced-table-search #advancedSearch [(filter)]=\"filter.value\" [collapsed]=\"true\" [table]=\"table\" [allowSave]=\"allowSaveOption\">\n <advanced-search>\n <app-advanced-search-form [form]=\"searchConfiguration\" (filterChange)=\"advancedSearch.asyncAdvancedSearch()\" #search [(filter)]=\"filter.value\"></app-advanced-search-form>\n </advanced-search>\n </app-advanced-table-search>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-3\">\n <a *ngIf=\"table && table.selected && table.selected.length\"\n class=\"text-danger text-decoration-none mr-2\" href=\"javascript:void(0)\" (click)=\"remove()\">\n <span>-</span><span>&nbsp;</span><span [translate]=\"'Tables.RemoveItem'\"></span>\n </a>\n <a class=\"text-indigo text-decoration-none\" [routerLink]=\"['.', { outlets:{ modal:'add'} }]\">\n <span>+</span><span>&nbsp;</span><span [translate]=\"'Tables.AddItem'\"></span>\n </a>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12 mb-4\">\n <app-advanced-table [selectable]=\"true\" #table\n [autoLoad]=false\n [showFooter]=\"false\"\n (load)=\"onDataLoad($event)\" [height]=\"600\"></app-advanced-table>\n </div>\n </div>\n <router-modal></router-modal>\n</div>\n"
2556
- }] }
2557
- ];
2558
- /** @nocollapse */
2559
- AdvancedListComponent.ctorParameters = function () { return [
2560
- { type: AngularDataContext },
2561
- { type: TranslateService },
2562
- { type: ActivatedRoute },
2563
- { type: ErrorService },
2564
- { type: ToastService },
2565
- { type: ModalService },
2566
- { type: UserActivityService }
2567
- ]; };
2568
- AdvancedListComponent.propDecorators = {
2569
- entitySet: [{ type: Input, args: ['entitySet',] }],
2570
- category: [{ type: Input, args: ['category',] }],
2571
- description: [{ type: Input, args: ['description',] }],
2572
- longDescription: [{ type: Input, args: ['longDescription',] }],
2573
- tableConfiguration: [{ type: Input, args: ['tableConfiguration',] }],
2574
- searchConfiguration: [{ type: Input, args: ['searchConfiguration',] }],
2575
- table: [{ type: ViewChild, args: ['table',] }],
2576
- allowSaveOption: [{ type: Input, args: ['allowSaveOption',] }]
2577
- };
2578
- return AdvancedListComponent;
2579
- }());
2580
-
2581
- var AdvancedRowActionComponent = /** @class */ (function (_super) {
2582
- __extends(AdvancedRowActionComponent, _super);
2583
- function AdvancedRowActionComponent(router, activatedRoute, _translateService, _context, _errorService, _modalService, _appEvent) {
2584
- var _this = _super.call(this, router, activatedRoute) || this;
2585
- _this._translateService = _translateService;
2586
- _this._context = _context;
2587
- _this._errorService = _errorService;
2588
- _this._modalService = _modalService;
2589
- _this._appEvent = _appEvent;
2590
- _this.modalIcon = 'fas fa-project-diagram';
2591
- _this.progressType = 'indigo';
2592
- _this.errorMessage = 'Tables.Actions.CompletedWithErrors';
2593
- _this.loading = false;
2594
- _this.refresh = new EventEmitter();
2595
- // set modal size
2596
- _this.modalClass = 'modal-lg';
2597
- // set modal title
2598
- _this.modalTitle = 'Tables.Actions.Label';
2599
- // disable ok button
2600
- _this.okButtonDisabled = false;
2601
- // set button text
2602
- _this.okButtonText = 'Tables.Actions.Start';
2603
- return _this;
2604
- }
2605
- Object.defineProperty(AdvancedRowActionComponent.prototype, "form", {
2606
- get: function () {
2607
- return this.formComponent;
2608
- },
2609
- enumerable: true,
2610
- configurable: true
2611
- });
2612
- AdvancedRowActionComponent.prototype.ngOnInit = function () {
2613
- var _this = this;
2614
- this.refreshSubscription = this.refresh.subscribe(function (value) {
2615
- if (value && value.progress) {
2616
- var progress = 0;
2617
- if (value.progress < 0) {
2618
- progress = 0;
2619
- }
2620
- else if (value.progress > 100) {
2621
- progress = 100;
2622
- }
2623
- else {
2624
- progress = value.progress;
2206
+ _this.configChangesSubscription = _this.advancedTable.configChanges.subscribe(function (config) {
2207
+ if (_this.tableConfig) {
2208
+ // reset default filter
2209
+ _this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
2210
+ // init filter
2211
+ _this.defaultFilters = [AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER];
2212
+ // add extra filters
2213
+ _this.defaultFilters.push.apply(_this.defaultFilters, _this.tableConfig.searches);
2625
2214
  }
2626
- _this.progressComponent.value = progress;
2627
- }
2215
+ });
2628
2216
  });
2629
2217
  };
2630
- AdvancedRowActionComponent.prototype.ngAfterViewInit = function () {
2631
- var _this = this;
2632
- if (this.formComponent && this.formComponent.form) {
2633
- this.okButtonDisabled = true;
2634
- this.invalidSubscription = this.formComponent.form.change.subscribe(function (event) {
2635
- if (Object.prototype.hasOwnProperty.call(event, "isValid") && (event.changed != null)) {
2636
- _this.okButtonDisabled = !event.isValid;
2637
- }
2638
- });
2639
- }
2218
+ AdvancedTableModalBaseComponent.prototype.cancel = function () {
2219
+ return this.close();
2640
2220
  };
2641
- AdvancedRowActionComponent.prototype.ngOnDestroy = function () {
2642
- if (this.refreshSubscription) {
2643
- this.refreshSubscription.unsubscribe();
2644
- }
2645
- if (this.executeSubscription) {
2646
- this.executeSubscription.unsubscribe();
2647
- }
2648
- if (this.invalidSubscription) {
2649
- this.invalidSubscription.unsubscribe();
2650
- }
2221
+ AdvancedTableModalBaseComponent.prototype.ok = function () {
2222
+ return this.close();
2651
2223
  };
2652
- AdvancedRowActionComponent.prototype.cancel = function () {
2653
- if (this.loading) {
2654
- return;
2224
+ AdvancedTableModalBaseComponent.prototype.ngOnDestroy = function () {
2225
+ if (this.subscription) {
2226
+ this.subscription.unsubscribe();
2655
2227
  }
2656
- // close
2657
- if (this._modalService.modalRef) {
2658
- return this._modalService.modalRef.hide();
2228
+ };
2229
+ AdvancedTableModalBaseComponent.prototype.onDataLoad = function (data) {
2230
+ this.recordsTotal = data.recordsTotal;
2231
+ this.recordsFiltered = data.recordsFiltered;
2232
+ // get first page info (because page is not going to be fired for first page)
2233
+ if (data.recordsTotal > 0 && this.pageInfo.recordsTotal === 0) {
2234
+ this.pageInfo.recordsTotal = data.recordsTotal;
2659
2235
  }
2660
2236
  };
2661
- AdvancedRowActionComponent.prototype.ok = function () {
2662
- return __awaiter(this, void 0, void 0, function () {
2663
- var _this = this;
2664
- return __generator(this, function (_a) {
2665
- try {
2666
- this.loading = true;
2667
- this.lastError = null;
2668
- if (this.formComponent && this.formComponent.form &&
2669
- this.formComponent.form.formio && this.formComponent.form.formio.data) {
2670
- // set data
2671
- this.data = this.formComponent.form.formio.data;
2672
- }
2673
- // do action
2674
- this.execute.subscribe(function (result) {
2675
- _this.loading = false;
2676
- _this.refresh.emit({
2677
- progress: 100
2678
- });
2679
- if (result && result.errors && result.errors > 0) {
2680
- // show message for partial success
2681
- if (result.errors === 1) {
2682
- _this.lastError = new Error(_this._translateService.instant(_this.errorMessage + ".Description.One"));
2683
- }
2684
- else {
2685
- _this.lastError = new Error(_this._translateService.instant(_this.errorMessage + ".Description.Many", result));
2686
- }
2687
- _this.refresh.emit({
2688
- progress: 1
2689
- });
2690
- return;
2691
- }
2692
- if (_this._modalService.modalRef) {
2693
- _this._modalService.modalRef.hide();
2694
- }
2695
- }, function (err) {
2696
- _this.loading = false;
2697
- _this.lastError = err;
2698
- _this.refresh.emit({
2699
- progress: 0
2700
- });
2701
- });
2702
- }
2703
- catch (err) {
2704
- this.loading = false;
2705
- this.lastError = err;
2706
- }
2707
- return [2 /*return*/];
2708
- });
2237
+ AdvancedTableModalBaseComponent.prototype.previousPage = function () {
2238
+ // go to next page
2239
+ // noinspection TypeScriptValidateJSTypes
2240
+ this.advancedTable.dataTable.page('previous').draw('page');
2241
+ };
2242
+ AdvancedTableModalBaseComponent.prototype.nextPage = function () {
2243
+ // go to next page
2244
+ // noinspection TypeScriptValidateJSTypes
2245
+ this.advancedTable.dataTable.page('next').draw('page');
2246
+ };
2247
+ AdvancedTableModalBaseComponent.prototype.onTableInit = function (dataTable) {
2248
+ var self = this;
2249
+ // get initial page info
2250
+ var initialPageInfo = dataTable.page.info();
2251
+ initialPageInfo.start += 1;
2252
+ self.pageInfo = initialPageInfo;
2253
+ // change emptyTableMessage
2254
+ dataTable.context[0].oLanguage.sEmptyTable = this.emptyTable.nativeElement.innerHTML;
2255
+ // bind page change event
2256
+ dataTable.on('page.dt', function () {
2257
+ var pageInfo = dataTable.page.info();
2258
+ pageInfo.start += 1;
2259
+ self.pageInfo = pageInfo;
2260
+ });
2261
+ // bind draw change event
2262
+ dataTable.on('draw.dt', function () {
2263
+ // for future use
2264
+ self.loading = false;
2265
+ var pageInfo = dataTable.page.info();
2266
+ pageInfo.start += 1;
2267
+ self.pageInfo = pageInfo;
2709
2268
  });
2710
2269
  };
2711
- AdvancedRowActionComponent.decorators = [
2712
- { type: Component, args: [{
2713
- selector: 'app-advanced-row-action',
2714
- template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0 mt-2 pb-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"col-12\">\n <div class=\"alert alert-warning\" role=\"alert\">\n <span>{{ 'Tables.Actions.CompletedWithErrors.Title' | translate }}</span><br>\n <small *ngIf=\"lastError.status >= 0\" [translate]=\"'E' + lastError.status + '.message'\"></small>\n <small *ngIf=\"lastError.status == null\">{{lastError.message}}</small>\n </div>\n </div>\n </div>\n <div class=\"row\" *ngIf=\"description\">\n <div class=\"col-12 mb-3\">\n <div class=\"text-justify\">\n {{description | translate}}\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <div *ngIf=\"items && items.length > 1\" [translate]=\"'Tables.Actions.ActionMessage.Many'\" [translateParams]=\"items\"></div>\n <div *ngIf=\"items && items.length === 1\" [translate]=\"'Tables.Actions.ActionMessage.One'\"></div>\n <div class=\"font-weight-bold text-danger\" *ngIf=\"items && items.length <= 0\" [translate]=\"'Tables.Actions.ActionMessage.None'\"></div>\n <div class=\"pt-2 font-weight-bold text-danger\" *ngIf=\"additionalMessage && items && items.length <= 0\">{{additionalMessage}}</div>\n </div>\n </div>\n <div class=\"row pt-3\" *ngIf=\"formTemplate\">\n <div class=\"col-12 mb-3\">\n <div>\n <advanced-form-edit #formComponent [formName]=\"formTemplate\" [(data)]=\"data\"></advanced-form-edit>\n </div>\n </div>\n </div>\n\n <div class=\"row mt-3\">\n <div class=\"col-12\">\n <progressbar #progress [type]=\"progressType\" [max]=\"100\">\n </progressbar>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || (items && items.length === 0)\" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{okButtonText | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{cancelButtonText | translate}}\n </button>\n </div>\n</div>\n",
2715
- encapsulation: ViewEncapsulation.None,
2716
- styles: ["\n .fa-1_5x {\n font-size: 1.5rem;\n }\n .form-control:disabled, .form-control[readonly] {\n background-color: inherit;\n }\n .form-check.checkbox {\n position: relative\n }\n "]
2717
- }] }
2718
- ];
2719
- /** @nocollapse */
2720
- AdvancedRowActionComponent.ctorParameters = function () { return [
2721
- { type: Router },
2722
- { type: ActivatedRoute },
2723
- { type: TranslateService },
2724
- { type: AngularDataContext },
2725
- { type: ErrorService },
2726
- { type: ModalService },
2727
- { type: AppEventService }
2728
- ]; };
2729
- AdvancedRowActionComponent.propDecorators = {
2730
- items: [{ type: Input }],
2731
- modalIcon: [{ type: Input }],
2732
- description: [{ type: Input }],
2733
- formTemplate: [{ type: Input }],
2734
- progressType: [{ type: Input }],
2735
- data: [{ type: Output }],
2736
- additionalMessage: [{ type: Input }],
2737
- errorMessage: [{ type: Input }],
2738
- progressComponent: [{ type: ViewChild, args: ['progress',] }],
2739
- formComponent: [{ type: ViewChild, args: ['formComponent',] }],
2740
- refresh: [{ type: Input }],
2741
- execute: [{ type: Input }]
2270
+ AdvancedTableModalBaseComponent.prototype.firstPage = function () {
2271
+ // go to first page
2272
+ // noinspection TypeScriptValidateJSTypes
2273
+ this.advancedTable.dataTable.page('first').draw('page');
2274
+ };
2275
+ AdvancedTableModalBaseComponent.prototype.lastPage = function () {
2276
+ // go to last page
2277
+ // noinspection TypeScriptValidateJSTypes
2278
+ this.advancedTable.dataTable.page('last').draw('page');
2742
2279
  };
2743
- return AdvancedRowActionComponent;
2744
- }(RouterModalOkCancel));
2745
-
2746
- var AdvancedTableSearchBaseComponent = /** @class */ (function () {
2747
- function AdvancedTableSearchBaseComponent() {
2748
- this.filterChange = new EventEmitter();
2749
- }
2750
- Object.defineProperty(AdvancedTableSearchBaseComponent.prototype, "filter", {
2751
- get: function () {
2752
- return this._filter;
2753
- },
2754
- set: function (value) {
2755
- this._filter = value;
2756
- },
2757
- enumerable: true,
2758
- configurable: true
2759
- });
2760
- AdvancedTableSearchBaseComponent.prototype.onKeyEnter = function (event) {
2280
+ AdvancedTableModalBaseComponent.prototype.setLength = function (value) {
2281
+ this.pageLength = value;
2282
+ this.advancedTable.dataTable.page.len(value).draw();
2283
+ };
2284
+ AdvancedTableModalBaseComponent.prototype.onKeyUp = function (event) {
2761
2285
  if (event.code === 'Enter') {
2762
- this.filterChange.emit(this._filter);
2286
+ // loading
2287
+ this.loading = true;
2288
+ this.advancedTable.search(event.target.value);
2763
2289
  }
2764
2290
  };
2765
- AdvancedTableSearchBaseComponent.propDecorators = {
2766
- filterChange: [{ type: Output }],
2767
- filter: [{ type: Input }]
2768
- };
2769
- return AdvancedTableSearchBaseComponent;
2770
- }());
2771
-
2772
- var AdvancedSearchFormComponent = /** @class */ (function (_super) {
2773
- __extends(AdvancedSearchFormComponent, _super);
2774
- function AdvancedSearchFormComponent(_context, _translateService, _activatedRoute, _http) {
2775
- var _this = _super.call(this) || this;
2776
- _this._context = _context;
2777
- _this._translateService = _translateService;
2778
- _this._activatedRoute = _activatedRoute;
2779
- _this._http = _http;
2780
- _this.form = {};
2781
- _this.refreshForm = new EventEmitter();
2782
- _this.submission = { data: {} };
2783
- _this.loading = true;
2784
- return _this;
2785
- }
2786
- AdvancedSearchFormComponent.prototype.ngOnChanges = function (changes) {
2787
- var _this = this;
2788
- if (Object.prototype.hasOwnProperty.call(changes, 'form')) {
2789
- if (changes.form != null) {
2790
- if (changes.form.currentValue &&
2791
- changes.form.currentValue != changes.form.previousValue) {
2792
- this.ngOnInit();
2793
- }
2794
- }
2291
+ /**
2292
+ *
2293
+ * Reads the modal table and returns a list of filters to use in the table
2294
+ * query.
2295
+ *
2296
+ * @param tableConfig {object} The table configuration from json file
2297
+ * @param defaultFilterValues {object} A list of default filters
2298
+ * @param {object} searchItem The searchItem to use
2299
+ *
2300
+ */
2301
+ AdvancedTableModalBaseComponent.prototype.getFilters = function (tableConfig, defaultFilterValues, searchItem) {
2302
+ if (defaultFilterValues === void 0) { defaultFilterValues = {}; }
2303
+ // Do nothing in absence of configuration.
2304
+ if (!tableConfig || !Array.isArray(tableConfig.criteria)) {
2305
+ return [];
2795
2306
  }
2796
- if (Object.prototype.hasOwnProperty.call(changes, 'formSrc')) {
2797
- if (changes.formSrc != null) {
2798
- if (changes.formSrc.currentValue &&
2799
- changes.formSrc.currentValue != changes.formSrc.previousValue) {
2800
- this._http.get(changes.formSrc.currentValue).toPromise().then(function (form) {
2801
- // set form
2802
- _this.form = form;
2803
- // and init
2804
- _this.ngOnInit();
2805
- }).catch(function (err) {
2806
- console.error('An error occurred while loading search configuration');
2807
- console.error(err);
2808
- });
2809
- }
2810
- }
2307
+ if (searchItem.filter == null) {
2308
+ return [];
2811
2309
  }
2812
- if (Object.prototype.hasOwnProperty.call(changes, 'filter')) {
2813
- if (changes.filter != null) {
2814
- this.submission.data = changes.filter.currentValue || {};
2815
- this.refreshForm.emit({
2816
- submission: this.submission
2817
- });
2818
- }
2310
+ var matchedCriterion = tableConfig.criteria.find(function (criterion) {
2311
+ return Object.prototype.hasOwnProperty.call(searchItem.filter, criterion.name);
2312
+ });
2313
+ if (matchedCriterion == null) {
2314
+ return [];
2819
2315
  }
2820
- };
2821
- AdvancedSearchFormComponent.prototype.ngOnInit = function () {
2822
- var _this = this;
2823
- if (this.form) {
2824
- new ServiceUrlPreProcessor(this._context).parse(this.form);
2825
- new TranslatePreProcessor(this._translateService).parse(this.form);
2826
- this.submission = {
2827
- data: this.filter
2828
- };
2829
- this.refreshForm.emit({
2830
- form: this.form
2831
- });
2832
- this.loading = false;
2833
- this.filterSubscription = this.filterChange.subscribe(function (filter) {
2834
- _this.submission.data = filter;
2835
- _this.refreshForm.emit({
2836
- submission: _this.submission
2837
- });
2316
+ var value = searchItem.filter[matchedCriterion.name];
2317
+ var criterionSafeName = matchedCriterion.name !== null
2318
+ ? matchedCriterion.name.toString()
2319
+ : '';
2320
+ var applicableFilter;
2321
+ // Raw dates should be transformed to a specific format
2322
+ if (criterionSafeName.includes('GMT')) {
2323
+ var newDate = this.datePipe.transform(criterionSafeName, 'MM/dd/yyyy');
2324
+ applicableFilter = this._template.transform(matchedCriterion.filter, {
2325
+ value: newDate
2838
2326
  });
2839
2327
  }
2328
+ else if (criterionSafeName !== 'undefined') {
2329
+ applicableFilter = (this._template.transform(matchedCriterion.filter, Object.assign({
2330
+ value: value
2331
+ }, defaultFilterValues)));
2332
+ }
2333
+ else {
2334
+ applicableFilter = '';
2335
+ }
2336
+ return [applicableFilter];
2840
2337
  };
2841
- AdvancedSearchFormComponent.prototype.onChange = function (event) {
2842
- var _this = this;
2843
- Object.keys(this.formComponent.submission.data).forEach(function (key) {
2844
- if (Object.prototype.hasOwnProperty.call(_this.formComponent.submission.data, key)) {
2845
- var value = _this.formComponent.submission.data[key];
2846
- // the filter with type is a string and is not empty
2847
- var isEmptyString = typeof value === 'string' && value.length === 0;
2848
- if (!isEmptyString) {
2849
- Object.defineProperty(_this.filter, key, {
2850
- configurable: true,
2851
- enumerable: true,
2852
- value: value
2853
- });
2854
- }
2855
- else {
2856
- delete _this.filter[key];
2338
+ AdvancedTableModalBaseComponent.prototype.onFilterSelect = function (value) {
2339
+ this.advancedSearch(value);
2340
+ };
2341
+ /**
2342
+ *
2343
+ * Runs a filter against the modal table
2344
+ *
2345
+ * @param {object} filter The filter to use in the search
2346
+ *
2347
+ */
2348
+ AdvancedTableModalBaseComponent.prototype.advancedSearch = function (filter) {
2349
+ return __awaiter(this, void 0, void 0, function () {
2350
+ var defaultFilterValues, err_1, expressions, predefinedCriteria, query;
2351
+ return __generator(this, function (_a) {
2352
+ switch (_a.label) {
2353
+ case 0:
2354
+ // Do nothing in absence of configuration.
2355
+ if (!this.tableConfig && !Array.isArray(this.tableConfig.criteria)) {
2356
+ console.warn('No table configuration available', this.tableConfig);
2357
+ return [2 /*return*/];
2358
+ }
2359
+ _a.label = 1;
2360
+ case 1:
2361
+ _a.trys.push([1, 3, , 4]);
2362
+ return [4 /*yield*/, this.advancedFilterValueProvider.getValues()];
2363
+ case 2:
2364
+ defaultFilterValues = _a.sent();
2365
+ return [3 /*break*/, 4];
2366
+ case 3:
2367
+ err_1 = _a.sent();
2368
+ defaultFilterValues = {};
2369
+ return [3 /*break*/, 4];
2370
+ case 4:
2371
+ expressions = [];
2372
+ if (filter) {
2373
+ this.defaultFilter = filter;
2374
+ predefinedCriteria = this.getFilters(this.tableConfig, defaultFilterValues, filter);
2375
+ }
2376
+ else {
2377
+ // Empty a falsy filter resets the results
2378
+ this.defaultFilter = AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER;
2379
+ }
2380
+ // search filter is applied separately, there is no need to add here.
2381
+ expressions.push(predefinedCriteria);
2382
+ query = this._context.model(this.advancedTable.config.model).asQueryable();
2383
+ query.setParam('filter', expressions.join(' and ')).prepare();
2384
+ this.advancedTable.query = query;
2385
+ this.advancedTable.fetch();
2386
+ return [2 /*return*/];
2857
2387
  }
2858
- }
2388
+ });
2859
2389
  });
2860
2390
  };
2861
- AdvancedSearchFormComponent.prototype.onFormLoad = function (form) {
2862
- var currentLang = this._translateService.currentLang;
2863
- this.formComponent.formio.i18next.options.resources[currentLang] = { translation: this._translateService.instant("Forms") };
2864
- this.formComponent.formio.language = currentLang;
2865
- };
2866
- AdvancedSearchFormComponent.prototype.ngAfterViewInit = function () {
2867
- //
2868
- };
2869
- AdvancedSearchFormComponent.prototype.ngOnDestroy = function () {
2870
- if (this.filterSubscription) {
2871
- this.filterSubscription.unsubscribe();
2872
- }
2391
+ AdvancedTableModalBaseComponent.DEFAULT_ALL_FILTER = {
2392
+ name: 'Tables.All',
2393
+ filter: null
2873
2394
  };
2874
- AdvancedSearchFormComponent.decorators = [
2395
+ AdvancedTableModalBaseComponent.decorators = [
2875
2396
  { type: Component, args: [{
2876
- selector: 'app-advanced-search-form',
2877
- template: "\n <div class=\"p-4\">\n <formio #formioComponent class=\"formio-search\" (keydown)=\"onKeyEnter($event)\" (change)=\"onChange($event)\" (formLoad)=\"onFormLoad($event)\"\n [refresh]=\"refreshForm\" [submission]=\"submission\" [form]=\"form\"></formio>\n </div>\n ",
2878
- encapsulation: ViewEncapsulation.None,
2879
- styles: ["formio.formio-search .form-group{margin-bottom:0}formio.formio-search .form-group .col-form-label{font-size:90%;padding-top:4px;padding-bottom:4px}.choices__list.choices__list--single .choices__item:first-child.choices__item--selectable{width:85%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}"]
2397
+ // tslint:disable-next-line: component-selector
2398
+ selector: 'app-advanced-table-modal',
2399
+ template: AdvancedTableModalBaseTemplate,
2400
+ styles: ["\n\n "]
2880
2401
  }] }
2881
2402
  ];
2882
2403
  /** @nocollapse */
2883
- AdvancedSearchFormComponent.ctorParameters = function () { return [
2884
- { type: AngularDataContext },
2885
- { type: TranslateService },
2404
+ AdvancedTableModalBaseComponent.ctorParameters = function () { return [
2405
+ { type: Router },
2886
2406
  { type: ActivatedRoute },
2887
- { type: HttpClient }
2407
+ { type: AngularDataContext },
2408
+ { type: AdvancedFilterValueProvider },
2409
+ { type: DatePipe }
2888
2410
  ]; };
2889
- AdvancedSearchFormComponent.propDecorators = {
2890
- formComponent: [{ type: ViewChild, args: ['formioComponent',] }],
2891
- form: [{ type: Input }],
2892
- formSrc: [{ type: Input }],
2893
- refreshForm: [{ type: Output }]
2411
+ AdvancedTableModalBaseComponent.propDecorators = {
2412
+ advancedTable: [{ type: ViewChild, args: ['advancedTable',] }],
2413
+ emptyTable: [{ type: ViewChild, args: ['emptyTable',] }],
2414
+ dropdownFilter: [{ type: ViewChild, args: ['dropdownFilter',] }],
2415
+ dropdownLength: [{ type: ViewChild, args: ['dropdownLength',] }],
2416
+ tableConfig: [{ type: Input, args: ['tableConfig',] }],
2417
+ tableConfigSrc: [{ type: Input, args: ['tableConfigSrc',] }],
2418
+ pageLength: [{ type: Input, args: ['pageLength',] }],
2419
+ searchText: [{ type: Input, args: ['searchText',] }],
2420
+ lengthMenu: [{ type: Input, args: ['lengthMenu',] }],
2421
+ defaultFilter: [{ type: Input, args: ['defaultFilter',] }]
2894
2422
  };
2895
- return AdvancedSearchFormComponent;
2896
- }(AdvancedTableSearchBaseComponent));
2423
+ return AdvancedTableModalBaseComponent;
2424
+ }(RouterModalOkCancel));
2897
2425
 
2898
2426
  var AdvancedSelectComponent = /** @class */ (function (_super) {
2899
2427
  __extends(AdvancedSelectComponent, _super);
@@ -2925,7 +2453,7 @@ var AdvancedSelectComponent = /** @class */ (function (_super) {
2925
2453
  { type: Component, args: [{
2926
2454
  // tslint:disable-next-line: component-selector
2927
2455
  selector: 'app-advanced-select',
2928
- template: "<div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button [disabled]=\"cancelButtonDisabled\" (click)=\"cancel()\" type=\"button\" class=\"close\" data-dismiss=\"modal\"\n aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div>\n <!-- search -->\n <div class=\"row mt-3\">\n <div class=\"col-12 col-lg-3\">\n <div class=\"input-group mb-3\">\n <input spellcheck=\"false\" type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"searchText\"\n class=\"form-control bg-gray-100 border-0\" placeholder=\"{{'Tables.SearchPlaceholder' | translate}}\"\n aria-label=\"Search\" aria-describedby=\"basic-addon2\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-default bg-gray-100 border-0\" type=\"button\">\n <i class=\"fa fa-search text-secondary\"></i>\n </button>\n </div>\n </div>\n </div>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n\n </div>\n </div>\n <div class=\"col-12 col-lg-5\">\n <div class=\"btn-toolbar\">\n <button class=\"btn btn-gray-100\">\n <i class=\"fa fa-sliders-h pr-2 text-secondary\" aria-hidden=\"true\"></i>{{'Tables.Filters' | translate}}\n </button>\n <div class=\"dropdown ml-3\">\n <button dropdownToggle class=\"btn btn-gray-100 dropdown-toggle\" type=\"button\" id=\"dropdownDefaultFilters\"\n data-toggle=\"dropdown\">\n {{ this.defaultFilter.name | translate }}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownDefaultFilters\">\n <a class=\"dropdown-item\" *ngFor=\"let filter of defaultFilters\"\n (click)=\"advancedSearch(filter.filter ? filter : '')\">\n {{ filter.name | translate }}\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col text-lg-right mt-3 mt-lg-0\">\n <button [disabled]=\"true\" class=\"btn rounded-pill btn-outline-theme\">\n <span class=\"pr-2 font-lg\">+</span><span [translate]=\"'Tables.AddItem'\"></span>\n </button>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\" [ngClass]=\"{ 'component-loading': loading}\">\n <app-advanced-table #advancedTable (init)=\"onTableInit($event)\" (load)=\"onDataLoad($event)\"\n [autoLoad]=\"true\"\n [selectable]=\"true\" [multipleSelect]=\"true\" [scrollX]=\"false\" [scrollY]=\"320\" [pageLength]=\"pageLength\"\n [scrollable]=\"false\" [showFooter]=\"false\" [showActions]=\"false\" [lengthMenu]=\"lengthMenu\"\n [config]=\"tableConfig\" [configSrc]=\"tableConfigSrc\"></app-advanced-table>\n </div>\n </div>\n <div class=\"row mt-3 table-custom-pager\">\n <div class=\"col-12 d-flex\" *ngIf=\"recordsTotal\">\n <div class=\"mt-2 ml-auto mr-3 text-secondary\" [translate]=\"'Tables.RecordsPerPage'\"></div>\n <div class=\"dropdown mr-3\">\n <button dropdownToggle class=\"btn btn-gray-100 dropdown-toggle\" type=\"button\" id=\"dropdownPageSize\"\n data-toggle=\"dropdown\">\n {{pageLength}}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownPageSize\">\n <button (click)=\"setLength(item)\" class=\"dropdown-item dropdown-item-theme\" type=\"button\"\n *ngFor=\"let item of lengthMenu\">{{item}}</button>\n </div>\n </div>\n <div class=\"mt-2 mr-2\" [translate]=\"'Tables.PageInfo'\" [translateParams]=\"pageInfo\"></div>\n <button [disabled]=\"pageInfo && pageInfo.page === 0\" class=\"btn text-nowrap\" (click)=\"firstPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===0\" class=\"btn\" (click)=\"previousPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn\" (click)=\"nextPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn text-nowrap\"\n (click)=\"lastPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled\" (click)=\"ok()\" type=\"button\" [ngClass]=\"okButtonClass\">\n {{okButtonText | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled\" (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\"\n data-dismiss=\"modal\">\n {{ cancelButtonText | translate}}\n </button>\n</div>\n",
2456
+ template: "<div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button [disabled]=\"cancelButtonDisabled\" (click)=\"cancel()\" type=\"button\" class=\"close\" data-dismiss=\"modal\"\n aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n</div>\n<div class=\"modal-body\">\n <div>\n <!-- search -->\n <div class=\"row mt-3\">\n <div class=\"col-12 col-lg-3\">\n <div class=\"input-group mb-3\">\n <input spellcheck=\"false\" type=\"text\" (keyup)=\"onKeyUp($event)\" [(ngModel)]=\"searchText\"\n class=\"form-control bg-gray-100 border-0\" placeholder=\"{{'Tables.SearchPlaceholder' | translate}}\"\n aria-label=\"Search\" aria-describedby=\"basic-addon2\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-default bg-gray-100 border-0\" type=\"button\">\n <i class=\"fa fa-search text-secondary\"></i>\n </button>\n </div>\n </div>\n </div>\n <div #emptyTable class=\"d-none\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n\n </div>\n </div>\n <div class=\"col-12 col-lg-5\">\n <div class=\"btn-toolbar\">\n <button class=\"btn btn-gray-100\">\n <i class=\"fa fa-sliders-h pr-2 text-secondary\" aria-hidden=\"true\"></i>{{'Tables.Filters' | translate}}\n </button>\n <div class=\"dropdown ml-3\">\n <button dropdownToggle class=\"btn btn-gray-100 dropdown-toggle\" type=\"button\" id=\"dropdownDefaultFilters\"\n data-toggle=\"dropdown\">\n {{ this.defaultFilter.name | translate }}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownDefaultFilters\">\n <a class=\"dropdown-item\" *ngFor=\"let filter of defaultFilters\"\n (click)=\"advancedSearch(filter.filter ? filter : '')\">\n {{ filter.name | translate }}\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col text-lg-right mt-3 mt-lg-0 d-none\">\n <button [disabled]=\"true\" class=\"btn rounded-pill btn-outline-theme\">\n <span class=\"pr-2 font-lg\">+</span><span [translate]=\"'Tables.AddItem'\"></span>\n </button>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\" [ngClass]=\"{ 'component-loading': loading}\">\n <app-advanced-table #advancedTable (init)=\"onTableInit($event)\" (load)=\"onDataLoad($event)\"\n [autoLoad]=\"true\"\n [selectable]=\"true\" [multipleSelect]=\"true\" [scrollX]=\"false\" [scrollY]=\"320\" [pageLength]=\"pageLength\"\n [scrollable]=\"false\" [showFooter]=\"false\" [showActions]=\"false\" [lengthMenu]=\"lengthMenu\"\n [config]=\"tableConfig\" [configSrc]=\"tableConfigSrc\"></app-advanced-table>\n </div>\n </div>\n <div class=\"row mt-3 table-custom-pager\">\n <div class=\"col-12 d-flex\" *ngIf=\"recordsTotal\">\n <div class=\"mt-2 ml-auto mr-3 text-secondary\" [translate]=\"'Tables.RecordsPerPage'\"></div>\n <div class=\"dropdown mr-3\">\n <button dropdownToggle class=\"btn btn-gray-100 dropdown-toggle\" type=\"button\" id=\"dropdownPageSize\"\n data-toggle=\"dropdown\">\n {{pageLength}}\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownPageSize\">\n <button (click)=\"setLength(item)\" class=\"dropdown-item dropdown-item-theme\" type=\"button\"\n *ngFor=\"let item of lengthMenu\">{{item}}</button>\n </div>\n </div>\n <div class=\"mt-2 mr-2\" [translate]=\"'Tables.PageInfo'\" [translateParams]=\"pageInfo\"></div>\n <button [disabled]=\"pageInfo && pageInfo.page === 0\" class=\"btn text-nowrap\" (click)=\"firstPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===0\" class=\"btn\" (click)=\"previousPage()\">\n <i class=\"fa fa-chevron-left text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn\" (click)=\"nextPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n <button [disabled]=\"pageInfo && pageInfo.page===pageInfo.pages-1\" class=\"btn text-nowrap\"\n (click)=\"lastPage()\">\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n <i class=\"fa fa-chevron-right text-color-theme\"></i>\n </button>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled\" (click)=\"ok()\" type=\"button\" [ngClass]=\"okButtonClass\">\n {{okButtonText | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled\" (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\"\n data-dismiss=\"modal\">\n {{ cancelButtonText | translate}}\n </button>\n</div>\n",
2929
2457
  encapsulation: ViewEncapsulation.None,
2930
2458
  styles: ["\n .modal-table .dataTables_wrapper {\n height: 50vh;\n overflow-y: auto;\n }\n "]
2931
2459
  }] }
@@ -3745,469 +3273,950 @@ var TableSimpleHeaderComponent = /** @class */ (function () {
3745
3273
  this.dataLoadSubscription.unsubscribe();
3746
3274
  return;
3747
3275
  }
3748
- }
3749
- if (changes.table.currentValue != changes.table.previousValue) {
3750
- this.dataLoadSubscription = changes.table.currentValue.load.subscribe(function (data) {
3751
- _this.recordsTotal = data.recordsTotal;
3752
- });
3753
- }
3754
- }
3276
+ }
3277
+ if (changes.table.currentValue != changes.table.previousValue) {
3278
+ this.dataLoadSubscription = changes.table.currentValue.load.subscribe(function (data) {
3279
+ _this.recordsTotal = data.recordsTotal;
3280
+ });
3281
+ }
3282
+ }
3283
+ };
3284
+ TableSimpleHeaderComponent.prototype.ngOnDestroy = function () {
3285
+ if (this.dataLoadSubscription) {
3286
+ this.dataLoadSubscription.unsubscribe();
3287
+ }
3288
+ };
3289
+ TableSimpleHeaderComponent.prototype.ngOnInit = function () {
3290
+ //
3291
+ };
3292
+ TableSimpleHeaderComponent.decorators = [
3293
+ { type: Component, args: [{
3294
+ selector: 'app-table-simple-header',
3295
+ template: "<div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 0\">\n <span>&nbsp;</span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-2\">\n <ng-content select=\"table-simple-header-tools\"></ng-content>\n </div>\n </div>\n</div>\n\n"
3296
+ }] }
3297
+ ];
3298
+ /** @nocollapse */
3299
+ TableSimpleHeaderComponent.ctorParameters = function () { return []; };
3300
+ TableSimpleHeaderComponent.propDecorators = {
3301
+ table: [{ type: Input }]
3302
+ };
3303
+ return TableSimpleHeaderComponent;
3304
+ }());
3305
+
3306
+ var AdvancedTableNotNullError = /** @class */ (function (_super) {
3307
+ __extends(AdvancedTableNotNullError, _super);
3308
+ function AdvancedTableNotNullError() {
3309
+ return _super.call(this, 'Advanced table component cannot be empty at this context.') || this;
3310
+ }
3311
+ return AdvancedTableNotNullError;
3312
+ }(Error));
3313
+ var AdvancedTableEditorDirective = /** @class */ (function () {
3314
+ function AdvancedTableEditorDirective(table) {
3315
+ this.table = table;
3316
+ this.dirty = false;
3317
+ this.dirtyChange = new EventEmitter(false);
3318
+ //
3319
+ }
3320
+ /**
3321
+ * Add rows to table and mark them as added rows
3322
+ */
3323
+ AdvancedTableEditorDirective.prototype.add = function () {
3324
+ var addItems = [];
3325
+ for (var _i = 0; _i < arguments.length; _i++) {
3326
+ addItems[_i] = arguments[_i];
3327
+ }
3328
+ var e_1, _a;
3329
+ if (this.table == null) {
3330
+ throw new AdvancedTableNotNullError();
3331
+ }
3332
+ // decorate items
3333
+ var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3334
+ try {
3335
+ for (var addItems_1 = __values(addItems), addItems_1_1 = addItems_1.next(); !addItems_1_1.done; addItems_1_1 = addItems_1.next()) {
3336
+ var element = addItems_1_1.value;
3337
+ var tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3338
+ if (tr.hasClass('removed')) {
3339
+ tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3340
+ }
3341
+ else {
3342
+ this.table.dataTable.rows.add([element]);
3343
+ tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3344
+ tr.toggleClass('added font-weight-bold text-success');
3345
+ }
3346
+ }
3347
+ }
3348
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3349
+ finally {
3350
+ try {
3351
+ if (addItems_1_1 && !addItems_1_1.done && (_a = addItems_1.return)) _a.call(addItems_1);
3352
+ }
3353
+ finally { if (e_1) throw e_1.error; }
3354
+ }
3355
+ this.table.dataTable.draw();
3356
+ // find removed
3357
+ var removedLength = this.table.dataTable.rows('.removed')[0].length;
3358
+ // find added
3359
+ var addedLength = this.table.dataTable.rows('.added')[0].length;
3360
+ // and emit event
3361
+ var items = this.table.dataTable.rows().data();
3362
+ this.table.load.emit({
3363
+ data: items,
3364
+ recordsFiltered: items.length - removedLength,
3365
+ recordsTotal: items.length - removedLength,
3366
+ });
3367
+ this.dirty = (removedLength > 0 || addedLength > 0);
3368
+ this.dirtyChange.emit(this.dirty);
3369
+ };
3370
+ /**
3371
+ * Marks rows as removed rows
3372
+ */
3373
+ AdvancedTableEditorDirective.prototype.remove = function () {
3374
+ var removeItems = [];
3375
+ for (var _i = 0; _i < arguments.length; _i++) {
3376
+ removeItems[_i] = arguments[_i];
3377
+ }
3378
+ var e_2, _a;
3379
+ if (this.table == null) {
3380
+ throw new AdvancedTableNotNullError();
3381
+ }
3382
+ // get key
3383
+ var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3384
+ var _loop_1 = function (element) {
3385
+ var tr = this_1.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3386
+ // if row is marked as added
3387
+ if (tr.hasClass('added')) {
3388
+ // remove this dirty row
3389
+ this_1.table.dataTable.rows(tr).remove();
3390
+ }
3391
+ else {
3392
+ // otherwise unmarked row
3393
+ tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3394
+ }
3395
+ // check if item is selected
3396
+ var selectedIndex = this_1.table.selected.findIndex(function (item) {
3397
+ return item[key] === element[key];
3398
+ });
3399
+ // and remove it from selected collection
3400
+ if (selectedIndex >= 0) {
3401
+ this_1.table.selected.splice(selectedIndex, 1);
3402
+ }
3403
+ };
3404
+ var this_1 = this;
3405
+ try {
3406
+ // loop items
3407
+ for (var removeItems_1 = __values(removeItems), removeItems_1_1 = removeItems_1.next(); !removeItems_1_1.done; removeItems_1_1 = removeItems_1.next()) {
3408
+ var element = removeItems_1_1.value;
3409
+ _loop_1(element);
3410
+ }
3411
+ }
3412
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
3413
+ finally {
3414
+ try {
3415
+ if (removeItems_1_1 && !removeItems_1_1.done && (_a = removeItems_1.return)) _a.call(removeItems_1);
3416
+ }
3417
+ finally { if (e_2) throw e_2.error; }
3418
+ }
3419
+ // re-draw table
3420
+ this.table.dataTable.draw();
3421
+ // get number of table items
3422
+ var items = this.table.dataTable.rows().data();
3423
+ // get number of removed items
3424
+ var removedLength = this.table.dataTable.rows('.removed')[0].length;
3425
+ // get number of added items
3426
+ var addedLength = this.table.dataTable.rows('.added')[0].length;
3427
+ // refresh
3428
+ this.table.load.emit({
3429
+ data: items,
3430
+ recordsFiltered: items.length - removedLength,
3431
+ recordsTotal: items.length - removedLength,
3432
+ });
3433
+ this.dirty = (removedLength > 0 || addedLength > 0);
3434
+ this.dirtyChange.emit(this.dirty);
3435
+ };
3436
+ AdvancedTableEditorDirective.prototype.set = function (items) {
3437
+ if (this.table == null) {
3438
+ throw new AdvancedTableNotNullError();
3439
+ }
3440
+ // clear rows
3441
+ this.table.selected = [];
3442
+ this.table.dataTable.clear();
3443
+ // set items
3444
+ this.table.dataTable.rows.add(items).draw();
3445
+ this.table.load.emit({
3446
+ data: items,
3447
+ recordsFiltered: items.length,
3448
+ recordsTotal: items.length,
3449
+ });
3450
+ };
3451
+ /**
3452
+ * Undo changes
3453
+ */
3454
+ AdvancedTableEditorDirective.prototype.undo = function () {
3455
+ if (this.table == null) {
3456
+ throw new AdvancedTableNotNullError();
3457
+ }
3458
+ // reset removed rows
3459
+ this.table.dataTable.rows('.removed').nodes().to$().toggleClass('removed text-gray-400 text-decoration-line-through');
3460
+ // remove added rows
3461
+ this.table.dataTable.rows('.added').remove();
3462
+ // clear selected items
3463
+ this.table.selected = [];
3464
+ var items = this.table.dataTable.rows().data();
3465
+ this.table.dataTable.draw();
3466
+ this.table.load.emit({
3467
+ data: items,
3468
+ recordsFiltered: items.length,
3469
+ recordsTotal: items.length,
3470
+ });
3471
+ this.dirty = false;
3472
+ this.dirtyChange.emit(this.dirty);
3473
+ };
3474
+ AdvancedTableEditorDirective.prototype.rows = function () {
3475
+ if (this.table == null) {
3476
+ throw new AdvancedTableNotNullError();
3477
+ }
3478
+ return Array.from(this.table.dataTable.rows(':not(.removed)').data());
3479
+ };
3480
+ AdvancedTableEditorDirective.decorators = [
3481
+ { type: Directive, args: [{
3482
+ // tslint:disable-next-line: directive-selector
3483
+ selector: '[tableEditor]',
3484
+ },] }
3485
+ ];
3486
+ /** @nocollapse */
3487
+ AdvancedTableEditorDirective.ctorParameters = function () { return [
3488
+ { type: AdvancedTableComponent }
3489
+ ]; };
3490
+ AdvancedTableEditorDirective.propDecorators = {
3491
+ dirtyChange: [{ type: Output }]
3492
+ };
3493
+ return AdvancedTableEditorDirective;
3494
+ }());
3495
+
3496
+ var MAX_EXPORT_ITEMS = 500;
3497
+ var BtnExpDirective = /** @class */ (function () {
3498
+ function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
3499
+ this._activatedTable = _activatedTable;
3500
+ this._context = _context;
3501
+ this._config = _config;
3502
+ this._translate = _translate;
3503
+ this._loadingService = _loadingService;
3504
+ this._errorService = _errorService;
3505
+ }
3506
+ BtnExpDirective.prototype.clickEvent = function (event) {
3507
+ return __awaiter(this, void 0, void 0, function () {
3508
+ var lastQuery, tableConfig, serviceHeaders, queryModel, query, queryParams, maxExportItems, url;
3509
+ return __generator(this, function (_a) {
3510
+ event.preventDefault();
3511
+ event.stopPropagation();
3512
+ if (this._activatedTable.activeTable) {
3513
+ lastQuery = this._activatedTable.activeTable.lastQuery;
3514
+ tableConfig = this._activatedTable.activeTable.config;
3515
+ serviceHeaders = this._context.getService().getHeaders();
3516
+ queryModel = lastQuery.getModel();
3517
+ query = this._context.model(queryModel).asQueryable();
3518
+ queryParams = lastQuery.getParams();
3519
+ query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
3520
+ maxExportItems = 1000;
3521
+ if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
3522
+ query.skip(0).take(maxExportItems);
3523
+ }
3524
+ else {
3525
+ query.skip(0).take(MAX_EXPORT_ITEMS);
3526
+ }
3527
+ url = this.constructURL(query);
3528
+ this.downloadFile(url, query.getService().getHeaders(), query.getModel());
3529
+ }
3530
+ return [2 /*return*/];
3531
+ });
3532
+ });
3755
3533
  };
3756
- TableSimpleHeaderComponent.prototype.ngOnDestroy = function () {
3757
- if (this.dataLoadSubscription) {
3758
- this.dataLoadSubscription.unsubscribe();
3534
+ /**
3535
+ * Sets the parameters to the query based on
3536
+ * the active filters of the activated table
3537
+ * @param {ClientDataQueryable} query
3538
+ * @param params: The filters of the last query of the activated table
3539
+ * @return ClientDataQueryable
3540
+ */
3541
+ BtnExpDirective.prototype.setParams = function (query, params) {
3542
+ if (params && typeof params === 'object') {
3543
+ Object.keys(params).forEach(function (key) {
3544
+ query.setParam(key, params[key]);
3545
+ });
3759
3546
  }
3547
+ return query;
3760
3548
  };
3761
- TableSimpleHeaderComponent.prototype.ngOnInit = function () {
3762
- //
3763
- };
3764
- TableSimpleHeaderComponent.decorators = [
3765
- { type: Component, args: [{
3766
- selector: 'app-table-simple-header',
3767
- template: "<div class=\"row\">\n <div class=\"col-auto mt-4\">\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 0\">\n <span>&nbsp;</span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal > 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Items'\"></span>\n </div>\n <div class=\"font-xl text-secondary\" *ngIf=\"recordsTotal === 1\">\n <span>{{recordsTotal}}</span><span>&nbsp;</span><span [translate]=\"'Tables.Item'\"></span>\n </div>\n </div>\n <div class=\"pull-right ml-auto mr-3 mt-3\">\n <div class=\"font-lg btn-toolbar mt-2\">\n <ng-content select=\"table-simple-header-tools\"></ng-content>\n </div>\n </div>\n</div>\n\n"
3768
- }] }
3769
- ];
3770
- /** @nocollapse */
3771
- TableSimpleHeaderComponent.ctorParameters = function () { return []; };
3772
- TableSimpleHeaderComponent.propDecorators = {
3773
- table: [{ type: Input }]
3549
+ /**
3550
+ * Sets the headers to the query based on
3551
+ * the default headers of the DataContext
3552
+ * and appending the accept header to get
3553
+ * an xlsx file from the API
3554
+ * @param {ClientDataQueryable} query
3555
+ * @param {Headers} headers: The headers to append to the query
3556
+ * @return ClientDataQueryable
3557
+ */
3558
+ BtnExpDirective.prototype.setHeaders = function (query, headers) {
3559
+ Object.keys(headers).forEach(function (key) {
3560
+ if (headers.hasOwnProperty(key)) {
3561
+ query.getService().setHeader(key, headers[key]);
3562
+ }
3563
+ });
3564
+ // sets a header to accept xlsx files
3565
+ query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
3566
+ return query;
3774
3567
  };
3775
- return TableSimpleHeaderComponent;
3776
- }());
3777
-
3778
- var AdvancedTableNotNullError = /** @class */ (function (_super) {
3779
- __extends(AdvancedTableNotNullError, _super);
3780
- function AdvancedTableNotNullError() {
3781
- return _super.call(this, 'Advanced table component cannot be empty at this context.') || this;
3782
- }
3783
- return AdvancedTableNotNullError;
3784
- }(Error));
3785
- var AdvancedTableEditorDirective = /** @class */ (function () {
3786
- function AdvancedTableEditorDirective(table) {
3787
- this.table = table;
3788
- this.dirty = false;
3789
- this.dirtyChange = new EventEmitter(false);
3790
- //
3791
- }
3792
3568
  /**
3793
- * Add rows to table and mark them as added rows
3569
+ * Constructs the select parameter of the
3570
+ * ClientDataQuery by replacing the target name
3571
+ * of the field based on the localized translation
3572
+ * of that property on the advanced tabled
3573
+ * @param {ClientDataQueryable} query
3574
+ * @param tableConfig: The configuration of the activated table
3575
+ * @return ClientDataQueryable
3794
3576
  */
3795
- AdvancedTableEditorDirective.prototype.add = function () {
3796
- var addItems = [];
3797
- for (var _i = 0; _i < arguments.length; _i++) {
3798
- addItems[_i] = arguments[_i];
3799
- }
3800
- var e_1, _a;
3801
- if (this.table == null) {
3802
- throw new AdvancedTableNotNullError();
3803
- }
3804
- // decorate items
3805
- var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3806
- try {
3807
- for (var addItems_1 = __values(addItems), addItems_1_1 = addItems_1.next(); !addItems_1_1.done; addItems_1_1 = addItems_1.next()) {
3808
- var element = addItems_1_1.value;
3809
- var tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3810
- if (tr.hasClass('removed')) {
3811
- tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3577
+ BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
3578
+ var _this = this;
3579
+ var selectQuery = query.getParams().$select;
3580
+ var selectQueryArray = selectQuery.split(',');
3581
+ selectQueryArray = selectQueryArray.map(function (select) {
3582
+ var e_1, _a, e_2, _b;
3583
+ var words = select.split(' ');
3584
+ if (words.length === 3) {
3585
+ if (tableConfig && tableConfig.columns) {
3586
+ try {
3587
+ for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
3588
+ var column = _d.value;
3589
+ if (column.property === words[2] && column.title) {
3590
+ words[2] = "\"" + _this._translate.instant(column.title) + "\"";
3591
+ }
3592
+ else if (column.property === words[2]) {
3593
+ words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
3594
+ }
3595
+ }
3596
+ }
3597
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3598
+ finally {
3599
+ try {
3600
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
3601
+ }
3602
+ finally { if (e_1) throw e_1.error; }
3603
+ }
3812
3604
  }
3813
- else {
3814
- this.table.dataTable.rows.add([element]);
3815
- tr = this.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3816
- tr.toggleClass('added font-weight-bold text-success');
3605
+ }
3606
+ if (words.length === 1) {
3607
+ if (tableConfig && tableConfig.columns) {
3608
+ try {
3609
+ for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
3610
+ var column = _f.value;
3611
+ if (column.name === words[0] && column.title) {
3612
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
3613
+ break;
3614
+ }
3615
+ else if (column.name === words[0] && column.property) {
3616
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
3617
+ break;
3618
+ }
3619
+ else if (words[0] === column.name && words[0] === "id" && column.hidden) {
3620
+ break;
3621
+ }
3622
+ else if (words[0] == column.name || words[0] === column.property) {
3623
+ words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
3624
+ }
3625
+ }
3626
+ }
3627
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
3628
+ finally {
3629
+ try {
3630
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
3631
+ }
3632
+ finally { if (e_2) throw e_2.error; }
3633
+ }
3817
3634
  }
3635
+ return words[0];
3818
3636
  }
3819
- }
3820
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3821
- finally {
3822
- try {
3823
- if (addItems_1_1 && !addItems_1_1.done && (_a = addItems_1.return)) _a.call(addItems_1);
3637
+ return words.join(' ');
3638
+ });
3639
+ selectQuery = selectQueryArray.join(',');
3640
+ query.setParam('$select', selectQuery);
3641
+ return query;
3642
+ };
3643
+ /**
3644
+ * Constructs the fetch URL based the query parameters
3645
+ * @param {ClientDataQueryable} query
3646
+ * @return String
3647
+ */
3648
+ BtnExpDirective.prototype.constructURL = function (query) {
3649
+ var baseURL = query.getService().getBase();
3650
+ var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
3651
+ Object.keys(query.getParams()).forEach(function (key, index) {
3652
+ if (index === 0) {
3653
+ url += key + '=' + query.getParams()[key];
3654
+ }
3655
+ else {
3656
+ url += '&' + key + '=' + query.getParams()[key];
3824
3657
  }
3825
- finally { if (e_1) throw e_1.error; }
3826
- }
3827
- this.table.dataTable.draw();
3828
- // find removed
3829
- var removedLength = this.table.dataTable.rows('.removed')[0].length;
3830
- // find added
3831
- var addedLength = this.table.dataTable.rows('.added')[0].length;
3832
- // and emit event
3833
- var items = this.table.dataTable.rows().data();
3834
- this.table.load.emit({
3835
- data: items,
3836
- recordsFiltered: items.length - removedLength,
3837
- recordsTotal: items.length - removedLength,
3838
3658
  });
3839
- this.dirty = (removedLength > 0 || addedLength > 0);
3840
- this.dirtyChange.emit(this.dirty);
3659
+ return url;
3841
3660
  };
3842
3661
  /**
3843
- * Marks rows as removed rows
3662
+ * Constructs the query by setting the parameters of the
3663
+ * advanced table's active filters, sets the necessary headers
3664
+ * and build the select parameter of the query
3665
+ * @param {ClientDataQueryable} query
3666
+ * @param params: The filters of the last query of the activated table
3667
+ * @param tableConfig: The configuration of the activated table
3668
+ * @param {Headers} headers: The headers to append to the query
3669
+ * @return ClientDataQueryable
3844
3670
  */
3845
- AdvancedTableEditorDirective.prototype.remove = function () {
3846
- var removeItems = [];
3847
- for (var _i = 0; _i < arguments.length; _i++) {
3848
- removeItems[_i] = arguments[_i];
3849
- }
3850
- var e_2, _a;
3851
- if (this.table == null) {
3852
- throw new AdvancedTableNotNullError();
3853
- }
3854
- // get key
3855
- var key = this.table.config.columns[0].property || this.table.config.columns[0].name;
3856
- var _loop_1 = function (element) {
3857
- var tr = this_1.table.dataTable.rows(':has(input[data-id="' + element[key] + '"])').nodes().to$();
3858
- // if row is marked as added
3859
- if (tr.hasClass('added')) {
3860
- // remove this dirty row
3861
- this_1.table.dataTable.rows(tr).remove();
3671
+ BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
3672
+ var _query = this.setParams(query, params);
3673
+ _query = this.setHeaders(_query, headers);
3674
+ _query = this.constructQueryParam(_query, tableConfig);
3675
+ return _query;
3676
+ };
3677
+ /**
3678
+ * Fetches and saves the xlsx file
3679
+ * @param {String} url
3680
+ * @param {Headers} serviceHeaders: The headers to append to the query
3681
+ * @param modelName: The model name of the advanced table
3682
+ */
3683
+ BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
3684
+ var _this = this;
3685
+ this._loadingService.showLoading();
3686
+ fetch(encodeURI(url), {
3687
+ headers: serviceHeaders,
3688
+ credentials: 'include'
3689
+ }).then(function (response) {
3690
+ if (response && !response.ok) {
3691
+ throw new ResponseError(response.statusText, response.status);
3692
+ }
3693
+ return response.blob();
3694
+ }).then(function (blob) {
3695
+ var objectUrl = window.URL.createObjectURL(blob);
3696
+ var a = document.createElement('a');
3697
+ document.body.appendChild(a);
3698
+ a.setAttribute('style', 'display: none');
3699
+ a.href = objectUrl;
3700
+ var downloadName = modelName + ".xlsx";
3701
+ a.download = downloadName;
3702
+ // this adds support for IE and MS Edge (up to version 44.19041)
3703
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
3704
+ window.navigator.msSaveOrOpenBlob(blob, downloadName);
3862
3705
  }
3863
3706
  else {
3864
- // otherwise unmarked row
3865
- tr.toggleClass('removed text-gray-400 text-decoration-line-through');
3707
+ // for all other browsers
3708
+ a.click();
3866
3709
  }
3867
- // check if item is selected
3868
- var selectedIndex = this_1.table.selected.findIndex(function (item) {
3869
- return item[key] === element[key];
3710
+ window.URL.revokeObjectURL(objectUrl);
3711
+ a.remove();
3712
+ _this._loadingService.hideLoading();
3713
+ }).catch(function (err) {
3714
+ _this._loadingService.hideLoading();
3715
+ _this._errorService.showError(err, {
3716
+ continueLink: '.'
3870
3717
  });
3871
- // and remove it from selected collection
3872
- if (selectedIndex >= 0) {
3873
- this_1.table.selected.splice(selectedIndex, 1);
3874
- }
3875
- };
3876
- var this_1 = this;
3877
- try {
3878
- // loop items
3879
- for (var removeItems_1 = __values(removeItems), removeItems_1_1 = removeItems_1.next(); !removeItems_1_1.done; removeItems_1_1 = removeItems_1.next()) {
3880
- var element = removeItems_1_1.value;
3881
- _loop_1(element);
3882
- }
3883
- }
3884
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3885
- finally {
3886
- try {
3887
- if (removeItems_1_1 && !removeItems_1_1.done && (_a = removeItems_1.return)) _a.call(removeItems_1);
3888
- }
3889
- finally { if (e_2) throw e_2.error; }
3890
- }
3891
- // re-draw table
3892
- this.table.dataTable.draw();
3893
- // get number of table items
3894
- var items = this.table.dataTable.rows().data();
3895
- // get number of removed items
3896
- var removedLength = this.table.dataTable.rows('.removed')[0].length;
3897
- // get number of added items
3898
- var addedLength = this.table.dataTable.rows('.added')[0].length;
3899
- // refresh
3900
- this.table.load.emit({
3901
- data: items,
3902
- recordsFiltered: items.length - removedLength,
3903
- recordsTotal: items.length - removedLength,
3904
3718
  });
3905
- this.dirty = (removedLength > 0 || addedLength > 0);
3906
- this.dirtyChange.emit(this.dirty);
3907
3719
  };
3908
- AdvancedTableEditorDirective.prototype.set = function (items) {
3909
- if (this.table == null) {
3910
- throw new AdvancedTableNotNullError();
3911
- }
3912
- // clear rows
3913
- this.table.selected = [];
3914
- this.table.dataTable.clear();
3915
- // set items
3916
- this.table.dataTable.rows.add(items).draw();
3917
- this.table.load.emit({
3918
- data: items,
3919
- recordsFiltered: items.length,
3920
- recordsTotal: items.length,
3921
- });
3720
+ BtnExpDirective.decorators = [
3721
+ { type: Directive, args: [{
3722
+ selector: '.universis-btn-export'
3723
+ },] }
3724
+ ];
3725
+ /** @nocollapse */
3726
+ BtnExpDirective.ctorParameters = function () { return [
3727
+ { type: ActivatedTableService },
3728
+ { type: AngularDataContext },
3729
+ { type: ConfigurationService },
3730
+ { type: TranslateService },
3731
+ { type: LoadingService },
3732
+ { type: ErrorService }
3733
+ ]; };
3734
+ BtnExpDirective.propDecorators = {
3735
+ clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
3922
3736
  };
3737
+ return BtnExpDirective;
3738
+ }());
3739
+
3740
+ var AdvancedAggregatorService = /** @class */ (function () {
3741
+ function AdvancedAggregatorService(_context, _template) {
3742
+ this._context = _context;
3743
+ this._template = _template;
3744
+ }
3923
3745
  /**
3924
- * Undo changes
3746
+ *
3747
+ * Formats and executes the data query
3748
+ *
3749
+ * @param {string} model The target model
3750
+ * @param {object} fixedParams Pairs of parameters to always be applied
3751
+ * @param {string} queryStatement The default query to use for fetching the data (e.g. expands etc)
3752
+ * @param {Array<string>} filters A list of filter expressions to append at the query
3753
+ * @param {string} searchTemplate The template to use for searching expressions
3754
+ * @param {string} searchValue The value of the user search
3755
+ *
3756
+ * @returns {Promise<any>} The response of the query execution
3925
3757
  */
3926
- AdvancedTableEditorDirective.prototype.undo = function () {
3927
- if (this.table == null) {
3928
- throw new AdvancedTableNotNullError();
3929
- }
3930
- // reset removed rows
3931
- this.table.dataTable.rows('.removed').nodes().to$().toggleClass('removed text-gray-400 text-decoration-line-through');
3932
- // remove added rows
3933
- this.table.dataTable.rows('.added').remove();
3934
- // clear selected items
3935
- this.table.selected = [];
3936
- var items = this.table.dataTable.rows().data();
3937
- this.table.dataTable.draw();
3938
- this.table.load.emit({
3939
- data: items,
3940
- recordsFiltered: items.length,
3941
- recordsTotal: items.length,
3758
+ AdvancedAggregatorService.prototype.fetchData = function (model, fixedParams, queryStatement, filters, searchTemplate, searchValue) {
3759
+ if (queryStatement === void 0) { queryStatement = ''; }
3760
+ return __awaiter(this, void 0, void 0, function () {
3761
+ var e_1, _a, query, filterExpressions, _b, _c, param, evaluatedSearch, words;
3762
+ var _this = this;
3763
+ return __generator(this, function (_d) {
3764
+ query = this._context.model(model).asQueryable();
3765
+ if (!fixedParams || typeof fixedParams !== 'object') {
3766
+ fixedParams = {};
3767
+ }
3768
+ filterExpressions = [];
3769
+ if (fixedParams) {
3770
+ try {
3771
+ for (_b = __values(Object.keys(fixedParams)), _c = _b.next(); !_c.done; _c = _b.next()) {
3772
+ param = _c.value;
3773
+ filterExpressions.push(param + " eq " + fixedParams[param]);
3774
+ }
3775
+ }
3776
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
3777
+ finally {
3778
+ try {
3779
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3780
+ }
3781
+ finally { if (e_1) throw e_1.error; }
3782
+ }
3783
+ }
3784
+ if (filters && Array.isArray(filters)) {
3785
+ filterExpressions = __spread(filterExpressions, filters);
3786
+ }
3787
+ if (searchTemplate && searchValue) {
3788
+ evaluatedSearch = void 0;
3789
+ if (/^"(.*?)"$/.test(searchValue)) { // validate search text in double quotes
3790
+ evaluatedSearch = this._template.transform(searchTemplate, __assign({}, fixedParams, { text: searchValue.replace(/^"|"$/g, '') }));
3791
+ }
3792
+ else {
3793
+ words = searchValue.split(' ');
3794
+ // join words to a single filter
3795
+ evaluatedSearch = words.map(function (word) {
3796
+ return _this._template.transform(searchTemplate, __assign({}, fixedParams, { text: word }));
3797
+ }).join(' and ');
3798
+ }
3799
+ filterExpressions.push(evaluatedSearch);
3800
+ }
3801
+ query.setParam('$filter', filterExpressions.join('and'));
3802
+ return [2 /*return*/, query.expand(queryStatement).take(-1).getItems()];
3803
+ });
3942
3804
  });
3943
- this.dirty = false;
3944
- this.dirtyChange.emit(this.dirty);
3945
3805
  };
3946
- AdvancedTableEditorDirective.prototype.rows = function () {
3947
- if (this.table == null) {
3948
- throw new AdvancedTableNotNullError();
3806
+ /**
3807
+ *
3808
+ * Formats the received data to use flat keys
3809
+ *
3810
+ * @param config The applied configuration
3811
+ * @param data The raw data
3812
+ *
3813
+ * @returns {Array<any>} The flat-key object list
3814
+ *
3815
+ */
3816
+ AdvancedAggregatorService.prototype.formatData = function (config, data) {
3817
+ var _this = this;
3818
+ try {
3819
+ return data.map(function (entry) {
3820
+ if (entry.subitems && Array.isArray(entry.subitems)) {
3821
+ entry.subitems = _this.formatData(config, entry.subitems);
3822
+ }
3823
+ var entryObject = {};
3824
+ for (var i = 0; i < config.columns.length; i++) {
3825
+ var keys = config.columns[i].name.split('/');
3826
+ var helperObject = entry[keys[0]];
3827
+ if (helperObject && keys.length > 1) {
3828
+ for (var i_1 = 1; i_1 < keys.length; i_1++) {
3829
+ if (helperObject === undefined || helperObject === null) {
3830
+ break;
3831
+ }
3832
+ else {
3833
+ helperObject = helperObject[keys[i_1]] !== undefined && helperObject[keys[i_1]] !== null
3834
+ ? helperObject[keys[i_1]]
3835
+ : undefined;
3836
+ }
3837
+ }
3838
+ }
3839
+ entryObject[config.columns[i].name] = helperObject;
3840
+ }
3841
+ if (entry.subitems) {
3842
+ entryObject.subitems = entry.subitems;
3843
+ }
3844
+ return entryObject;
3845
+ });
3846
+ }
3847
+ catch (err) {
3848
+ console.error(err);
3949
3849
  }
3950
- return Array.from(this.table.dataTable.rows(':not(.removed)').data());
3951
3850
  };
3952
- AdvancedTableEditorDirective.decorators = [
3953
- { type: Directive, args: [{
3954
- // tslint:disable-next-line: directive-selector
3955
- selector: '[tableEditor]',
3851
+ AdvancedAggregatorService.decorators = [
3852
+ { type: Injectable, args: [{
3853
+ providedIn: 'root'
3956
3854
  },] }
3957
3855
  ];
3958
3856
  /** @nocollapse */
3959
- AdvancedTableEditorDirective.ctorParameters = function () { return [
3960
- { type: AdvancedTableComponent }
3857
+ AdvancedAggregatorService.ctorParameters = function () { return [
3858
+ { type: AngularDataContext },
3859
+ { type: TemplatePipe }
3961
3860
  ]; };
3962
- AdvancedTableEditorDirective.propDecorators = {
3963
- dirtyChange: [{ type: Output }]
3964
- };
3965
- return AdvancedTableEditorDirective;
3861
+ AdvancedAggregatorService.ngInjectableDef = defineInjectable({ factory: function AdvancedAggregatorService_Factory() { return new AdvancedAggregatorService(inject(AngularDataContext), inject(TemplatePipe)); }, token: AdvancedAggregatorService, providedIn: "root" });
3862
+ return AdvancedAggregatorService;
3966
3863
  }());
3967
3864
 
3968
- var MAX_EXPORT_ITEMS = 500;
3969
- var BtnExpDirective = /** @class */ (function () {
3970
- function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
3971
- this._activatedTable = _activatedTable;
3972
- this._context = _context;
3973
- this._config = _config;
3974
- this._translate = _translate;
3865
+ /**
3866
+ *
3867
+ * @class AdvancedAggregatorComponent
3868
+ * @classdesc An advanced list with the capability of aggregate data based on configurable filters
3869
+ *
3870
+ */
3871
+ var AdvancedAggregatorComponent = /** @class */ (function () {
3872
+ function AdvancedAggregatorComponent(_changeDetector, _advancedAggregatorService, _loadingService) {
3873
+ this._changeDetector = _changeDetector;
3874
+ this._advancedAggregatorService = _advancedAggregatorService;
3975
3875
  this._loadingService = _loadingService;
3976
- this._errorService = _errorService;
3876
+ this.groups = [];
3877
+ this.eventHandler = new EventEmitter();
3977
3878
  }
3978
- BtnExpDirective.prototype.clickEvent = function (event) {
3879
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "config", {
3880
+ get: function () {
3881
+ return this._config;
3882
+ },
3883
+ set: function (value) {
3884
+ this._config = value;
3885
+ },
3886
+ enumerable: true,
3887
+ configurable: true
3888
+ });
3889
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "aggregators", {
3890
+ get: function () {
3891
+ return this._aggregators;
3892
+ },
3893
+ set: function (value) {
3894
+ this._aggregators = value;
3895
+ },
3896
+ enumerable: true,
3897
+ configurable: true
3898
+ });
3899
+ Object.defineProperty(AdvancedAggregatorComponent.prototype, "postProcessors", {
3900
+ get: function () {
3901
+ return this._postProcessors;
3902
+ },
3903
+ set: function (value) {
3904
+ this._postProcessors = value;
3905
+ },
3906
+ enumerable: true,
3907
+ configurable: true
3908
+ });
3909
+ AdvancedAggregatorComponent.prototype.ngOnInit = function () {
3979
3910
  return __awaiter(this, void 0, void 0, function () {
3980
- var lastQuery, tableConfig, serviceHeaders, queryModel, query, queryParams, maxExportItems, url;
3911
+ var _this = this;
3981
3912
  return __generator(this, function (_a) {
3982
- event.preventDefault();
3983
- event.stopPropagation();
3984
- if (this._activatedTable.activeTable) {
3985
- lastQuery = this._activatedTable.activeTable.lastQuery;
3986
- tableConfig = this._activatedTable.activeTable.config;
3987
- serviceHeaders = this._context.getService().getHeaders();
3988
- queryModel = lastQuery.getModel();
3989
- query = this._context.model(queryModel).asQueryable();
3990
- queryParams = lastQuery.getParams();
3991
- query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
3992
- maxExportItems = 1000;
3993
- if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
3994
- query.skip(0).take(maxExportItems);
3995
- }
3996
- else {
3997
- query.skip(0).take(MAX_EXPORT_ITEMS);
3998
- }
3999
- url = this.constructURL(query);
4000
- this.downloadFile(url, query.getService().getHeaders(), query.getModel());
4001
- }
3913
+ this.selectedGroups$.subscribe(function (data) {
3914
+ _this.groups = data;
3915
+ _this._changeDetector.markForCheck();
3916
+ });
3917
+ this.filters$.subscribe(function (filters) { return __awaiter(_this, void 0, void 0, function () {
3918
+ var err_1;
3919
+ return __generator(this, function (_a) {
3920
+ switch (_a.label) {
3921
+ case 0:
3922
+ _a.trys.push([0, 2, , 3]);
3923
+ return [4 /*yield*/, this.fetch(filters)];
3924
+ case 1:
3925
+ _a.sent();
3926
+ return [3 /*break*/, 3];
3927
+ case 2:
3928
+ err_1 = _a.sent();
3929
+ console.error(err_1);
3930
+ return [3 /*break*/, 3];
3931
+ case 3: return [2 /*return*/];
3932
+ }
3933
+ });
3934
+ }); });
4002
3935
  return [2 /*return*/];
4003
3936
  });
4004
3937
  });
4005
3938
  };
4006
- /**
4007
- * Sets the parameters to the query based on
4008
- * the active filters of the activated table
4009
- * @param {ClientDataQueryable} query
4010
- * @param params: The filters of the last query of the activated table
4011
- * @return ClientDataQueryable
4012
- */
4013
- BtnExpDirective.prototype.setParams = function (query, params) {
4014
- if (params && typeof params === 'object') {
4015
- Object.keys(params).forEach(function (key) {
4016
- query.setParam(key, params[key]);
3939
+ AdvancedAggregatorComponent.prototype.ngOnDestroy = function () {
3940
+ return __awaiter(this, void 0, void 0, function () {
3941
+ return __generator(this, function (_a) {
3942
+ this.selectedGroups$.unsubscribe();
3943
+ this.filters$.unsubscribe();
3944
+ return [2 /*return*/];
4017
3945
  });
4018
- }
4019
- return query;
3946
+ });
4020
3947
  };
4021
3948
  /**
4022
- * Sets the headers to the query based on
4023
- * the default headers of the DataContext
4024
- * and appending the accept header to get
4025
- * an xlsx file from the API
4026
- * @param {ClientDataQueryable} query
4027
- * @param {Headers} headers: The headers to append to the query
4028
- * @return ClientDataQueryable
3949
+ *
3950
+ * Retrieves the data
3951
+ *
4029
3952
  */
4030
- BtnExpDirective.prototype.setHeaders = function (query, headers) {
4031
- Object.keys(headers).forEach(function (key) {
4032
- if (headers.hasOwnProperty(key)) {
4033
- query.getService().setHeader(key, headers[key]);
4034
- }
3953
+ AdvancedAggregatorComponent.prototype.fetch = function (filters) {
3954
+ return __awaiter(this, void 0, void 0, function () {
3955
+ var data, i, err_2;
3956
+ return __generator(this, function (_a) {
3957
+ switch (_a.label) {
3958
+ case 0:
3959
+ _a.trys.push([0, 6, 7, 8]);
3960
+ this._loadingService.showLoading();
3961
+ return [4 /*yield*/, this._advancedAggregatorService.fetchData(this.config.model, this.params, this.config.query, filters.filters, this.searchExpression, filters.text)];
3962
+ case 1:
3963
+ data = _a.sent();
3964
+ if (!(this.postProcessors && Object.keys(this.postProcessors).length > 0 && this.config.postProcessors && this.config.postProcessors.length > 0)) return [3 /*break*/, 5];
3965
+ i = 0;
3966
+ _a.label = 2;
3967
+ case 2:
3968
+ if (!(i < this.config.postProcessors.length)) return [3 /*break*/, 5];
3969
+ return [4 /*yield*/, this.postProcessors[this.config.postProcessors[i].name](data)];
3970
+ case 3:
3971
+ data = _a.sent();
3972
+ _a.label = 4;
3973
+ case 4:
3974
+ i++;
3975
+ return [3 /*break*/, 2];
3976
+ case 5:
3977
+ this.body = this._advancedAggregatorService.formatData(this.config, data);
3978
+ this._changeDetector.markForCheck();
3979
+ return [3 /*break*/, 8];
3980
+ case 6:
3981
+ err_2 = _a.sent();
3982
+ console.error(err_2);
3983
+ return [3 /*break*/, 8];
3984
+ case 7:
3985
+ this._loadingService.hideLoading();
3986
+ return [7 /*endfinally*/];
3987
+ case 8: return [2 /*return*/];
3988
+ }
3989
+ });
4035
3990
  });
4036
- // sets a header to accept xlsx files
4037
- query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
4038
- return query;
4039
3991
  };
4040
3992
  /**
4041
- * Constructs the select parameter of the
4042
- * ClientDataQuery by replacing the target name
4043
- * of the field based on the localized translation
4044
- * of that property on the advanced tabled
4045
- * @param {ClientDataQueryable} query
4046
- * @param tableConfig: The configuration of the activated table
4047
- * @return ClientDataQueryable
3993
+ *
3994
+ * Triggers the event handler event
3995
+ *
3996
+ * @param {*} event The event data
3997
+ *
4048
3998
  */
4049
- BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
4050
- var _this = this;
4051
- var selectQuery = query.getParams().$select;
4052
- var selectQueryArray = selectQuery.split(',');
4053
- selectQueryArray = selectQueryArray.map(function (select) {
4054
- var e_1, _a, e_2, _b;
4055
- var words = select.split(' ');
4056
- if (words.length === 3) {
4057
- if (tableConfig && tableConfig.columns) {
4058
- try {
4059
- for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
4060
- var column = _d.value;
4061
- if (column.property === words[2] && column.title) {
4062
- words[2] = "\"" + _this._translate.instant(column.title) + "\"";
4063
- }
4064
- else if (column.property === words[2]) {
4065
- words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
4066
- }
4067
- }
4068
- }
4069
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
4070
- finally {
4071
- try {
4072
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
4073
- }
4074
- finally { if (e_1) throw e_1.error; }
4075
- }
4076
- }
4077
- }
4078
- if (words.length === 1) {
4079
- if (tableConfig && tableConfig.columns) {
4080
- try {
4081
- for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
4082
- var column = _f.value;
4083
- if (column.name === words[0] && column.title) {
4084
- words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
4085
- break;
4086
- }
4087
- else if (column.name === words[0] && column.property) {
4088
- words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
4089
- break;
4090
- }
4091
- else if (words[0] === column.name && words[0] === "id" && column.hidden) {
4092
- break;
4093
- }
4094
- else if (words[0] == column.name || words[0] === column.property) {
4095
- words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
4096
- }
4097
- }
4098
- }
4099
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
4100
- finally {
4101
- try {
4102
- if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
4103
- }
4104
- finally { if (e_2) throw e_2.error; }
4105
- }
4106
- }
4107
- return words[0];
4108
- }
4109
- return words.join(' ');
3999
+ AdvancedAggregatorComponent.prototype.onActionEvent = function (event) {
4000
+ this.eventHandler.emit(event);
4001
+ };
4002
+ AdvancedAggregatorComponent.decorators = [
4003
+ { type: Component, args: [{
4004
+ selector: 'app-advanced-aggregator',
4005
+ template: "<ng-container *ngIf=\"config && body\">\n <div class=\"w-100 text-center\" *ngIf=\"body && body.length === 0\">\n <div>\n <div class=\"mt-4\">\n <div class=\"icon-circle bg-gray-300 border-gray-100\"></div>\n </div>\n <div class=\"mt-4\">\n <h4 class=\"font-3xl text-dark\" [translate]=\"'Tables.EmptyTableTitle'\"></h4>\n <p class=\"font-lg text-dark\" [translate]=\"'Tables.EmptyTableMessage'\"></p>\n </div>\n </div>\n </div>\n <ng-container *ngIf=\"groups.length === 0\">\n <div class=\"row mt-4\">\n <app-advanced-aggregator-list [body]=\"body\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\" class=\"col-12\">\n </app-advanced-aggregator-list>\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ body | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"groups.length === 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <app-advanced-aggregator-list [body]=\"group.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for the group -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ group.value | callAggregator: aggregators: aggregator.name }} </span>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"groups.length > 1\">\n <ng-container *ngFor=\"let group of body | groupBy: groups[0].name | keyvalue\">\n <div class=\"row mt-4\">\n <h4 class=\"col text-secondary\"> {{ groups[0].title | aggregatorListTitle: group.key }} </h4>\n <div *ngFor=\"let subgroup of group.value | groupBy: groups[1].name | keyvalue\" class=\"col-12 ml-4 pl-4\">\n <div class=\"row mt-4\">\n <h6 class=\"col-12 text-secondary\"> {{ groups[1].title | aggregatorListTitle: subgroup.key }} </h6>\n <app-advanced-aggregator-list [body]=\"subgroup.value\" [config]=\"config\" (clickEvent)=\"onActionEvent($event)\"\n class=\"col-12\">\n </app-advanced-aggregator-list>\n </div>\n\n <!-- Footer for each subgroup -->\n <div *ngIf=\"config.aggregators && config.aggregators.length > 0\"\n class=\"footer-text text-dark font-weight-normal text-right font-sm mt-3 mr-2 w-100\">\n <div *ngFor=\"let aggregator of config.aggregators\">\n <span *ngIf=\"aggregator.label\"> {{ aggregator.label | translate }} </span>:\n <span class=\"font-weight-bold\"> {{ subgroup.value | callAggregator: aggregators: aggregator.name }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</ng-container>",
4006
+ changeDetection: ChangeDetectionStrategy.OnPush
4007
+ }] }
4008
+ ];
4009
+ /** @nocollapse */
4010
+ AdvancedAggregatorComponent.ctorParameters = function () { return [
4011
+ { type: ChangeDetectorRef },
4012
+ { type: AdvancedAggregatorService },
4013
+ { type: LoadingService }
4014
+ ]; };
4015
+ AdvancedAggregatorComponent.propDecorators = {
4016
+ config: [{ type: Input, args: ['config',] }],
4017
+ aggregators: [{ type: Input, args: ['aggregators',] }],
4018
+ postProcessors: [{ type: Input, args: ['postProcessors',] }],
4019
+ params: [{ type: Input, args: ['params',] }],
4020
+ selectedGroups$: [{ type: Input, args: ['selectedGroups',] }],
4021
+ filters$: [{ type: Input, args: ['filters',] }],
4022
+ searchExpression: [{ type: Input, args: ['searchExpression',] }],
4023
+ eventHandler: [{ type: Output }]
4024
+ };
4025
+ return AdvancedAggregatorComponent;
4026
+ }());
4027
+
4028
+ var Lengths;
4029
+ (function (Lengths) {
4030
+ Lengths["XL"] = "xl";
4031
+ Lengths["LG"] = "lg";
4032
+ Lengths["MD"] = "md";
4033
+ Lengths["SM"] = "sm";
4034
+ Lengths["XS"] = "xs";
4035
+ })(Lengths || (Lengths = {}));
4036
+ var AdvancedAggregatorListComponent = /** @class */ (function () {
4037
+ function AdvancedAggregatorListComponent(_template) {
4038
+ this._template = _template;
4039
+ this.clickEvent = new EventEmitter();
4040
+ }
4041
+ AdvancedAggregatorListComponent.prototype.ngOnInit = function () {
4042
+ var _this = this;
4043
+ this.config.columns.forEach(function (x) {
4044
+ x.length = Object.values(Lengths).includes(x.length) ? _this._template.transform("sis--list-group-item_" + x.length + "_column", x) :
4045
+ !x.length ? 'sis--list-group-item_sm_column' : x.length;
4110
4046
  });
4111
- selectQuery = selectQueryArray.join(',');
4112
- query.setParam('$select', selectQuery);
4113
- return query;
4114
4047
  };
4115
4048
  /**
4116
- * Constructs the fetch URL based the query parameters
4117
- * @param {ClientDataQueryable} query
4118
- * @return String
4049
+ *
4050
+ * Triggers the output event emitter
4051
+ *
4052
+ * @param type The type of the event as it's declared in the configuration
4053
+ * @param item The value of the current item
4054
+ * }
4119
4055
  */
4120
- BtnExpDirective.prototype.constructURL = function (query) {
4121
- var baseURL = query.getService().getBase();
4122
- var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
4123
- Object.keys(query.getParams()).forEach(function (key, index) {
4124
- if (index === 0) {
4125
- url += key + '=' + query.getParams()[key];
4126
- }
4127
- else {
4128
- url += '&' + key + '=' + query.getParams()[key];
4129
- }
4056
+ AdvancedAggregatorListComponent.prototype.callCallback = function (type, data) {
4057
+ this.clickEvent.emit({
4058
+ type: type,
4059
+ data: data
4130
4060
  });
4131
- return url;
4132
4061
  };
4133
- /**
4134
- * Constructs the query by setting the parameters of the
4135
- * advanced table's active filters, sets the necessary headers
4136
- * and build the select parameter of the query
4137
- * @param {ClientDataQueryable} query
4138
- * @param params: The filters of the last query of the activated table
4139
- * @param tableConfig: The configuration of the activated table
4140
- * @param {Headers} headers: The headers to append to the query
4141
- * @return ClientDataQueryable
4142
- */
4143
- BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
4144
- var _query = this.setParams(query, params);
4145
- _query = this.setHeaders(_query, headers);
4146
- _query = this.constructQueryParam(_query, tableConfig);
4147
- return _query;
4062
+ AdvancedAggregatorListComponent.decorators = [
4063
+ { type: Component, args: [{
4064
+ selector: 'app-advanced-aggregator-list',
4065
+ template: "<div id=\"group-list\" class=\"flex-column\" *ngIf=\"config && config.columns\">\n <ul class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item text-wrap\">\n <div class=\"d-flex justify-content-center align-items-center\" *ngIf=\"body && body.length > 0\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column\"></div>\n <div *ngFor=\"let column of config.columns; let i = index\" class=\"text-left\"\n [class]=\"config.columns[i].length\"\n [translate]=\"config.columns[i].type === 'action' ? '' : column.title\" [ngClass]=\"{\n 'd-none': config.columns[i].hidden\n }\"></div>\n </div>\n </li>\n </ul>\n\n <!-- The list of entries -->\n <ul class=\"sis--list-group sis--list-group-body\" *ngIf=\"body && body.length > 0\">\n <li class=\"sis--list-group-item text-wrap\" *ngFor=\"let entry of body | orderBy: config.orderBy\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <!-- The list of actions -->\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, entry)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n\n </div>\n <!-- The list of data -->\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && entry[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !entry[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && entry[column.name] && entry[column.name].length <= 3\n }\">\n {{entry[column.name] || '-'}}\n </span>\n\n <button *ngIf=\"config.columns[i].type === 'action' && config.columns[i].variant === 'edit'\"\n (click)=\"callCallback(config.columns[i].identifier, entry)\"\n [title]=\"(config.columns[i].title ? config.columns[i].title : '') | translate \"\n class=\"btn btn-default px-0 mx-0\">\n <i class=\"fas fa-edit text-indigo\"></i>\n </button>\n\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': entry[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"entry[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n <div *ngIf=\"entry && entry.subitems\">\n <div *ngFor=\"let subitem of entry.subitems\" class=\"d-flex justify-content-center align-items-center list-color\">\n <div *ngIf=\"config.actions && config.actions.length > 0\" class=\"sis--list-group-item_sm_column text-left pr-0\">\n <span class=\"px-0\">\n <i class=\"fa fa-fw\">&nbsp;</i>\n </span>\n <button *ngFor=\"let action of config.actions\" (click)=\"callCallback(action.identifier, subitem)\"\n [title]=\"(action.title ? action.title : '') | translate \" class=\"btn btn-default px-0\">\n <i *ngIf=\"action.type === 'edit'\" class=\"fas fa-edit text-indigo\"></i>\n </button>\n </div>\n <div class=\"text-left\"></div>\n <div *ngFor=\"let column of config.columns; let i=index\" [class]=\"config.columns[i].length\" class=\"text-left\"\n [ngClass]=\"{\n 'text-truncate': config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate,\n 'd-none': config.columns[i].hidden,\n 'd-md-block': !config.columns[i].hidden\n }\"\n [title]=\"config.columns[i].hasOwnProperty('truncate') && config.columns[i].truncate ? entry[column.name] : ''\">\n <span class=\"text-secondary\"\n *ngIf=\"!config.columns[i].hasOwnProperty('type') || (config.columns[i].hasOwnProperty('type') && config.columns[i].type === 'text')\"\n [ngClass]=\"{\n 'font-xs': config.columns[i].variant !== 'primary',\n 'text-body': config.columns[i].variant === 'primary',\n 'text-success': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && subitem[config.columns[i].condition],\n 'text-danger': config.columns[i].variant === 'redGreen' && config.columns[i].hasOwnProperty('condition') && !subitem[config.columns[i].condition],\n 'font-lg': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length > 3,\n 'font-2xl': config.columns[i].variant === 'redGreen' && subitem[column.name] && subitem[column.name].length <= 3\n }\">\n {{subitem[column.name] || '-'}}\n </span>\n <span *ngIf=\"config.columns[i].type === 'boolean'\">\n <i class=\"fa font-lg\" [ngClass]=\"{\n 'fa-check text-success': subitem[column.name].toString() === config.columns[i].trueValue,\n 'fa-times text-danger': subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant !== 'checkOrDash'\n }\"></i>\n <span\n *ngIf=\"subitem[column.name].toString() !== config.columns[i].trueValue && config.columns[i].variant === 'checkOrDash'\"\n class=\"text-secondary font-xs\">-</span>\n </span>\n </div>\n </div>\n </div>\n </li>\n </ul>\n</div>\n"
4066
+ }] }
4067
+ ];
4068
+ /** @nocollapse */
4069
+ AdvancedAggregatorListComponent.ctorParameters = function () { return [
4070
+ { type: TemplatePipe }
4071
+ ]; };
4072
+ AdvancedAggregatorListComponent.propDecorators = {
4073
+ config: [{ type: Input }],
4074
+ body: [{ type: Input }],
4075
+ clickEvent: [{ type: Output }]
4148
4076
  };
4149
- /**
4150
- * Fetches and saves the xlsx file
4151
- * @param {String} url
4152
- * @param {Headers} serviceHeaders: The headers to append to the query
4153
- * @param modelName: The model name of the advanced table
4154
- */
4155
- BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
4077
+ return AdvancedAggregatorListComponent;
4078
+ }());
4079
+
4080
+ var AddItemsComponent = /** @class */ (function (_super) {
4081
+ __extends(AddItemsComponent, _super);
4082
+ function AddItemsComponent(router, activatedRoute, _errorService, _modalService, _appEvent, _toastService, _loadingService, _translateService, _context) {
4083
+ var _this = _super.call(this, router, activatedRoute) || this;
4084
+ _this._errorService = _errorService;
4085
+ _this._modalService = _modalService;
4086
+ _this._appEvent = _appEvent;
4087
+ _this._toastService = _toastService;
4088
+ _this._loadingService = _loadingService;
4089
+ _this._translateService = _translateService;
4090
+ _this._context = _context;
4091
+ _this.loading = false;
4092
+ _this.items = [];
4093
+ _this.messages = [];
4094
+ // set modal size
4095
+ _this.modalClass = 'modal-lg';
4096
+ _this.okButtonDisabled = true;
4097
+ return _this;
4098
+ }
4099
+ AddItemsComponent.prototype.ngOnInit = function () {
4156
4100
  var _this = this;
4157
- this._loadingService.showLoading();
4158
- fetch(encodeURI(url), {
4159
- headers: serviceHeaders,
4160
- credentials: 'include'
4161
- }).then(function (response) {
4162
- if (response && !response.ok) {
4163
- throw new ResponseError(response.statusText, response.status);
4164
- }
4165
- return response.blob();
4166
- }).then(function (blob) {
4167
- var objectUrl = window.URL.createObjectURL(blob);
4168
- var a = document.createElement('a');
4169
- document.body.appendChild(a);
4170
- a.setAttribute('style', 'display: none');
4171
- a.href = objectUrl;
4172
- var downloadName = modelName + ".xlsx";
4173
- a.download = downloadName;
4174
- // this adds support for IE and MS Edge (up to version 44.19041)
4175
- if (window.navigator && window.navigator.msSaveOrOpenBlob) {
4176
- window.navigator.msSaveOrOpenBlob(blob, downloadName);
4101
+ this.selectedSubscription = this.selectComponent.advancedTable.selectedItems.subscribe(function (items) {
4102
+ if (_this.formName == null) {
4103
+ _this.okButtonDisabled = items.length === 0;
4177
4104
  }
4178
- else {
4179
- // for all other browsers
4180
- a.click();
4105
+ });
4106
+ if (this.formName != null) {
4107
+ this.formChangeSubscription = this.formComponent.form.change.subscribe(function (event) {
4108
+ if (Object.prototype.hasOwnProperty.call(event, 'isValid')) {
4109
+ // enable or disable button based on form status
4110
+ _this.okButtonDisabled = (!event.isValid);
4111
+ }
4112
+ });
4113
+ }
4114
+ if (this.target) {
4115
+ var target = this.target;
4116
+ }
4117
+ };
4118
+ AddItemsComponent.prototype.cancel = function () {
4119
+ this.clearMessages();
4120
+ if (this.loading) {
4121
+ return;
4122
+ }
4123
+ // close
4124
+ if (this._modalService.modalRef) {
4125
+ return this._modalService.modalRef.hide();
4126
+ }
4127
+ };
4128
+ AddItemsComponent.prototype.ngOnDestroy = function () {
4129
+ if (this.formLoadSubscription) {
4130
+ this.formLoadSubscription.unsubscribe();
4131
+ }
4132
+ if (this.formChangeSubscription) {
4133
+ this.formChangeSubscription.unsubscribe();
4134
+ }
4135
+ if (this.selectedSubscription) {
4136
+ this.selectedSubscription.unsubscribe();
4137
+ }
4138
+ };
4139
+ Object.defineProperty(AddItemsComponent.prototype, "formData", {
4140
+ get: function () {
4141
+ if (this.formComponent === null) {
4142
+ return null;
4181
4143
  }
4182
- window.URL.revokeObjectURL(objectUrl);
4183
- a.remove();
4184
- _this._loadingService.hideLoading();
4185
- }).catch(function (err) {
4186
- _this._loadingService.hideLoading();
4187
- _this._errorService.showError(err, {
4188
- continueLink: '.'
4144
+ return this.formComponent.form.formio.data;
4145
+ },
4146
+ enumerable: true,
4147
+ configurable: true
4148
+ });
4149
+ AddItemsComponent.prototype.ok = function () {
4150
+ var _this = this;
4151
+ try {
4152
+ this.clearMessages();
4153
+ return new Promise(function (resolve, reject) {
4154
+ _this.loading = false;
4155
+ _this.lastError = null;
4156
+ // set courses
4157
+ _this.items = _this.selectComponent.advancedTable.selected;
4158
+ // execute add
4159
+ _this.executeSubscription = _this.execute.subscribe(function (result) {
4160
+ _this.loading = false;
4161
+ if (_this.executeSubscription) {
4162
+ _this.executeSubscription.unsubscribe();
4163
+ }
4164
+ // close modal
4165
+ if (_this._modalService.modalRef) {
4166
+ _this._modalService.modalRef.hide();
4167
+ }
4168
+ return resolve();
4169
+ }, function (err) {
4170
+ _this.loading = false;
4171
+ // ensure that loading is hidden
4172
+ _this._loadingService.hideLoading();
4173
+ // set last error
4174
+ _this.lastError = err;
4175
+ return resolve();
4176
+ });
4189
4177
  });
4190
- });
4178
+ }
4179
+ catch (err) {
4180
+ this.loading = false;
4181
+ this._loadingService.hideLoading();
4182
+ this.lastError = err;
4183
+ }
4191
4184
  };
4192
- BtnExpDirective.decorators = [
4193
- { type: Directive, args: [{
4194
- selector: '.universis-btn-export'
4195
- },] }
4185
+ AddItemsComponent.prototype.onChange = function ($event) { };
4186
+ AddItemsComponent.prototype.clearMessages = function () {
4187
+ this.messages = [];
4188
+ };
4189
+ AddItemsComponent.prototype.onFilterChange = function (event) { };
4190
+ AddItemsComponent.decorators = [
4191
+ { type: Component, args: [{
4192
+ selector: 'app-add-items',
4193
+ template: "<div>\n <div class=\"modal-header\" *ngIf=\"modalTitle\">\n <h5 class=\"modal-title\">{{modalTitle | translate}}</h5>\n <button (click)=\"cancel()\" [disabled]=\"loading\"\n type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body pt-0\">\n <div class=\"row\" *ngIf=\"lastError\">\n <div class=\"alert alert-danger col-12\" role=\"alert\">\n <span [translate]=\"'E' + (lastError.statusCode || 500) + '.title'\"></span><br>\n <small *ngIf=\"lastError.statusCode >= 0\" [translate]=\"'E' + (lastError.statusCode || 500) + '.message'\"></small>\n <small *ngIf=\"lastError.statusCode == null\">{{lastError.message}}</small>\n </div>\n </div>\n <div class=\"row d-none\" *ngIf=\"items\">\n <div class=\"col-12\">\n <p [translate]=\"'StudyPrograms.AddCoursesHelp'\" [translateParams]=\"items\" ></p>\n </div>\n </div>\n <div class=\"row mt-3\">\n <div class=\"col-12\">\n <ng-container>\n <ul style=\"margin-left: -24px\" class=\"nav nav-tabs mb-1\" id=\"myTab\" role=\"tablist\">\n <li class=\"nav-item\" *ngIf=\"tableConfiguration\">\n <a class=\"nav-link active\" id=\"courses-tab\" data-toggle=\"tab\" href=\"#courses\" role=\"tab\" aria-controls=\"home\" aria-selected=\"true\" [translate]=\"'AddItems.SelectCourses'\" ></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"formName\">\n <a class=\"nav-link\" [ngClass]=\"{ 'disabled': !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) }\" id=\"attributes-tab\" data-toggle=\"tab\" href=\"#attributes\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.EditAttributes'\"></a>\n </li>\n <li class=\"nav-item\" *ngIf=\"messages && messages.length > 0\">\n <a class=\"nav-link\" id=\"messages-tab\" data-toggle=\"tab\" href=\"#messages\" role=\"tab\" aria-controls=\"profile\" aria-selected=\"false\" [translate]=\"'AddItems.Messages'\"></a>\n </li>\n </ul>\n <div class=\"tab-content border-0\" id=\"myTabContent\">\n <div class=\"tab-pane fade show active\" id=\"courses\" role=\"tabpanel\" aria-labelledby=\"home-tab\">\n <app-advanced-table-modal #selectComponent (filter)=\"onFilterChange($event)\" [tableConfig]=\"tableConfiguration\"></app-advanced-table-modal>\n </div>\n <div class=\"tab-pane fade\" id=\"attributes\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(formName == null)}\">\n<!-- <advanced-form-edit #formComponent [formName]=\"formName\" ></advanced-form-edit>-->\n </div>\n <div class=\"tab-pane fade\" id=\"messages\" role=\"tabpanel\" aria-labelledby=\"profile-tab\"\n [ngClass]=\"{'invisible':(messages == null)}\">\n <ul *ngIf=\"messages && messages.length>0\" class=\"sis--list-group sis--list-group-header\">\n <li class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center\">\n <div class=\"sis--list-group-item_lg_column\" [translate]=\"'AddItems.Messages'\"></div>\n </div>\n </li>\n </ul>\n <ul class=\"sis--list-group sis--list-group-body\">\n <li *ngFor=\"let message of messages\" class=\"sis--list-group-item\">\n <div class=\"d-flex justify-content-center align-items-center list-color\">\n <div class=\"sis--list-group-item_lg_column\">{{ message?.message }}</div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"messages && messages.length>0\">\n <button [disabled]=\"loading\" (click)=\"clearMessages()\" type=\"button\" class=\"btn btn-indigo mt-3\">\n {{'Clear' | translate}}\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"modal-footer justify-content-end\">\n <button [disabled]=\"okButtonDisabled || loading || !(selectComponent.advancedTable.selected && selectComponent.advancedTable.selected.length) \" (click)=\"ok()\"\n type=\"button\" [ngClass]=\"okButtonClass\">\n {{'OK' | translate}}\n </button>\n <button [disabled]=\"cancelButtonDisabled || loading\"\n (click)=\"cancel()\" type=\"button\" [ngClass]=\"cancelButtonClass\" data-dismiss=\"modal\">\n {{'Cancel' | translate}}\n </button>\n </div>\n</div>\n"
4194
+ }] }
4196
4195
  ];
4197
4196
  /** @nocollapse */
4198
- BtnExpDirective.ctorParameters = function () { return [
4199
- { type: ActivatedTableService },
4200
- { type: AngularDataContext },
4201
- { type: ConfigurationService },
4202
- { type: TranslateService },
4197
+ AddItemsComponent.ctorParameters = function () { return [
4198
+ { type: Router },
4199
+ { type: ActivatedRoute },
4200
+ { type: ErrorService },
4201
+ { type: ModalService },
4202
+ { type: AppEventService },
4203
+ { type: ToastService },
4203
4204
  { type: LoadingService },
4204
- { type: ErrorService }
4205
+ { type: TranslateService },
4206
+ { type: AngularDataContext }
4205
4207
  ]; };
4206
- BtnExpDirective.propDecorators = {
4207
- clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
4208
+ AddItemsComponent.propDecorators = {
4209
+ execute: [{ type: Input }],
4210
+ items: [{ type: Input }],
4211
+ target: [{ type: Input }],
4212
+ tableConfiguration: [{ type: Input }],
4213
+ formName: [{ type: Input }],
4214
+ messages: [{ type: Input }],
4215
+ formComponent: [{ type: ViewChild, args: ['formComponent',] }],
4216
+ selectComponent: [{ type: ViewChild, args: ['selectComponent',] }]
4208
4217
  };
4209
- return BtnExpDirective;
4210
- }());
4218
+ return AddItemsComponent;
4219
+ }(RouterModalOkCancel));
4211
4220
 
4212
4221
  /**
4213
4222
  *
@@ -4297,6 +4306,7 @@ var TABLES_EL = {
4297
4306
  "Search": "Αναζήτηση",
4298
4307
  "SearchPlaceholder": "Αναζήτηση...",
4299
4308
  "GroupBy": "Ομαδοποίηση ανά",
4309
+ "NotDefined": "Μη προσδιορισμένο",
4300
4310
  "DataTable": {
4301
4311
  "paginate": {
4302
4312
  "first": "Πρώτη σελίδα",
@@ -4400,6 +4410,7 @@ var TABLES_EN = {
4400
4410
  "Search": "Search",
4401
4411
  "SearchPlaceholder": "Search...",
4402
4412
  "GroupBy": "Group by",
4413
+ "NotDefined": "Not defined",
4403
4414
  "DataTable": {
4404
4415
  "paginate": {
4405
4416
  "first": "First",
@@ -4601,6 +4612,6 @@ var TablesModule = /** @class */ (function () {
4601
4612
  * Generated bundle index. Do not edit.
4602
4613
  */
4603
4614
 
4604
- export { AddItemsComponent, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AdvancedListComponent, AdvancedRowActionComponent, AdvancedSearchFormComponent, AdvancedSelectComponent, AdvancedSelectService, AdvancedTableConfigurationResolver, AdvancedSearchConfigurationResolver, AdvancedColumnFormatter, NestedPropertyFormatter, ButtonFormatter, LinkFormatter, ActionLinkFormatter, ActionButtonFormatter, ActionSplitButtonFormatter, SelectRowFormatter, TemplateFormatter, TrueFalseFormatter, TranslationFormatter, DateTimeFormatter, NgClassFormatter, LanguageFormatter, COLUMN_FORMATTERS, AdvancedTableConfiguration, AdvancedTableComponent, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, BtnExpDirective, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ɵ0, ActivatedTableService };
4615
+ export { AdvancedListComponent, AdvancedRowActionComponent, AdvancedSearchFormComponent, AdvancedSelectComponent, AdvancedSelectService, AdvancedTableConfigurationResolver, AdvancedSearchConfigurationResolver, AdvancedColumnFormatter, NestedPropertyFormatter, ButtonFormatter, LinkFormatter, ActionLinkFormatter, ActionButtonFormatter, ActionSplitButtonFormatter, SelectRowFormatter, TemplateFormatter, TrueFalseFormatter, TranslationFormatter, DateTimeFormatter, NgClassFormatter, LanguageFormatter, COLUMN_FORMATTERS, AdvancedTableConfiguration, AdvancedTableComponent, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ɵ0, ActivatedTableService };
4605
4616
 
4606
4617
  //# sourceMappingURL=universis-ngx-tables.js.map