@universis/ngx-tables 0.8.0 → 0.8.2

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.
@@ -3,15 +3,16 @@ import * as jQuery_ from 'jquery';
3
3
  import 'datatables.net';
4
4
  import 'datatables.net-scroller';
5
5
  import 'datatables.net-colreorder';
6
+ import 'datatables.net-buttons';
6
7
  import 'rxjs/add/observable/combineLatest';
7
8
  import { HttpClient } from '@angular/common/http';
8
- import { ClientDataQueryable, ResponseError, TextUtils } from '@themost/client';
9
+ import { ResponseError, ClientDataQueryable, TextUtils } from '@themost/client';
9
10
  import { BehaviorSubject } from 'rxjs';
10
11
  import { AngularDataContext } from '@themost/angular';
11
12
  import { DatePipe, CommonModule } from '@angular/common';
12
13
  import { TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
13
14
  import { FormControl, FormArray, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
14
- import { TemplatePipe, ModalService, LoadingService, ErrorService, DIALOG_BUTTONS, UserActivityService, ToastService, AppEventService, UserStorageService, ConfigurationService, SharedModule } from '@universis/common';
15
+ import { TemplatePipe, ModalService, ConfigurationService, ErrorService, LoadingService, DIALOG_BUTTONS, ExportSpreadsheetService, UserActivityService, ToastService, AppEventService, UserStorageService, SharedModule } from '@universis/common';
15
16
  import { RouterModalOkCancel, RouterModalModule } from '@universis/common/routing';
16
17
  import { ServiceUrlPreProcessor, TranslatePreProcessor, AdvancedFormsModule } from '@universis/forms';
17
18
  import { FormioModule } from 'angular-formio';
@@ -23,7 +24,7 @@ import { __extends, __awaiter, __generator, __values, __assign, __spread } from
23
24
  import { Injectable, Directive, Optional, Input, Pipe, Component, ElementRef, ViewChild, ViewEncapsulation, EventEmitter, Output, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, HostListener, ChangeDetectorRef, InjectionToken, Inject, Injector, ChangeDetectionStrategy } from '@angular/core';
24
25
  import { ActivatedRoute, Router, NavigationStart, NavigationEnd, RouterModule } from '@angular/router';
25
26
  import { createFeatureSelector, createSelector, select, Store } from '@ngrx/store';
26
- import { first, filter } from 'rxjs/operators';
27
+ import { skip, first, filter } from 'rxjs/operators';
27
28
 
28
29
  var AdvancedColumnFormatter = /** @class */ (function () {
29
30
  function AdvancedColumnFormatter() {
@@ -819,6 +820,303 @@ var ColumnSelectorService = /** @class */ (function () {
819
820
  return ColumnSelectorService;
820
821
  }());
821
822
 
823
+ var ActivatedTableService = /** @class */ (function () {
824
+ function ActivatedTableService(_router, _activatedRoute) {
825
+ var _this = this;
826
+ this._router = _router;
827
+ this._activatedRoute = _activatedRoute;
828
+ /**
829
+ * Get the last table that was set as active
830
+ * Note: Emitted value may be null (e.g. reset on route changes)
831
+ */
832
+ this.lastActiveTable = new BehaviorSubject(null);
833
+ /**
834
+ * Omit the last emitted value to observe only new active table changes
835
+ * Note: Emitted value may be null (e.g. reset on route changes)
836
+ */
837
+ this.nextActiveTable = this.lastActiveTable.pipe(skip(1));
838
+ _router.events.forEach(function (event) {
839
+ if (event instanceof NavigationStart) {
840
+ if (_this._activeTable) {
841
+ _this.activeTable = null;
842
+ }
843
+ }
844
+ });
845
+ }
846
+ Object.defineProperty(ActivatedTableService.prototype, "activeTable", {
847
+ get: function () {
848
+ return this._activeTable;
849
+ },
850
+ set: function (tableComponent) {
851
+ this._activeTable = tableComponent;
852
+ // provide change to observers
853
+ this.lastActiveTable.next(this._activeTable);
854
+ },
855
+ enumerable: true,
856
+ configurable: true
857
+ });
858
+ ActivatedTableService.decorators = [
859
+ { type: Injectable, args: [{
860
+ providedIn: 'root'
861
+ },] }
862
+ ];
863
+ /** @nocollapse */
864
+ ActivatedTableService.ctorParameters = function () { return [
865
+ { type: Router },
866
+ { type: ActivatedRoute }
867
+ ]; };
868
+ ActivatedTableService.ngInjectableDef = defineInjectable({ factory: function ActivatedTableService_Factory() { return new ActivatedTableService(inject(Router), inject(ActivatedRoute)); }, token: ActivatedTableService, providedIn: "root" });
869
+ return ActivatedTableService;
870
+ }());
871
+
872
+ var MAX_EXPORT_ITEMS = 500;
873
+ var BtnExpDirective = /** @class */ (function () {
874
+ function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
875
+ this._activatedTable = _activatedTable;
876
+ this._context = _context;
877
+ this._config = _config;
878
+ this._translate = _translate;
879
+ this._loadingService = _loadingService;
880
+ this._errorService = _errorService;
881
+ }
882
+ BtnExpDirective.prototype.clickEvent = function (event) {
883
+ return __awaiter(this, void 0, void 0, function () {
884
+ return __generator(this, function (_a) {
885
+ event.preventDefault();
886
+ event.stopPropagation();
887
+ if (this._activatedTable.activeTable) {
888
+ return [2 /*return*/, this._activatedTable.activeTable.exportView()];
889
+ /*
890
+ const lastQuery = this._activatedTable.activeTable.lastQuery;
891
+ const tableConfig = this._activatedTable.activeTable.config;
892
+ const serviceHeaders = this._context.getService().getHeaders();
893
+ const queryModel = lastQuery.getModel();
894
+ let query = this._context.model(queryModel).asQueryable();
895
+ const queryParams = lastQuery.getParams();
896
+ query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
897
+ // get export settings
898
+ const exportSettings = this._config.settings as ExportLimitConfiguration;
899
+ // get export limit
900
+ const maxExportItems = exportSettings && exportSettings.tables && exportSettings.tables.exportLimit;
901
+ if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
902
+ query.skip(0).take(maxExportItems);
903
+ } else {
904
+ query.skip(0).take(MAX_EXPORT_ITEMS);
905
+ }
906
+ // This constructs the URI based on the way @themost does
907
+ const url = this.constructURL(query);
908
+ this.downloadFile(url, query.getService().getHeaders(), query.getModel()); */
909
+ }
910
+ return [2 /*return*/];
911
+ });
912
+ });
913
+ };
914
+ /**
915
+ * Sets the parameters to the query based on
916
+ * the active filters of the activated table
917
+ * @param {ClientDataQueryable} query
918
+ * @param params: The filters of the last query of the activated table
919
+ * @return ClientDataQueryable
920
+ */
921
+ BtnExpDirective.prototype.setParams = function (query, params) {
922
+ if (params && typeof params === 'object') {
923
+ Object.keys(params).forEach(function (key) {
924
+ query.setParam(key, params[key]);
925
+ });
926
+ }
927
+ return query;
928
+ };
929
+ /**
930
+ * Sets the headers to the query based on
931
+ * the default headers of the DataContext
932
+ * and appending the accept header to get
933
+ * an xlsx file from the API
934
+ * @param {ClientDataQueryable} query
935
+ * @param {Headers} headers: The headers to append to the query
936
+ * @return ClientDataQueryable
937
+ */
938
+ BtnExpDirective.prototype.setHeaders = function (query, headers) {
939
+ Object.keys(headers).forEach(function (key) {
940
+ if (headers.hasOwnProperty(key)) {
941
+ query.getService().setHeader(key, headers[key]);
942
+ }
943
+ });
944
+ // sets a header to accept xlsx files
945
+ query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
946
+ return query;
947
+ };
948
+ /**
949
+ * Constructs the select parameter of the
950
+ * ClientDataQuery by replacing the target name
951
+ * of the field based on the localized translation
952
+ * of that property on the advanced tabled
953
+ * @param {ClientDataQueryable} query
954
+ * @param tableConfig: The configuration of the activated table
955
+ * @return ClientDataQueryable
956
+ */
957
+ BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
958
+ var _this = this;
959
+ var selectQuery = query.getParams().$select;
960
+ var selectQueryArray = selectQuery.split(',');
961
+ selectQueryArray = selectQueryArray.map(function (select$$1) {
962
+ var e_1, _a, e_2, _b;
963
+ var words = select$$1.split(' ');
964
+ if (words.length === 3) {
965
+ if (tableConfig && tableConfig.columns) {
966
+ try {
967
+ for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
968
+ var column = _d.value;
969
+ if (column.property === words[2] && column.title) {
970
+ words[2] = "\"" + _this._translate.instant(column.title) + "\"";
971
+ }
972
+ else if (column.property === words[2]) {
973
+ words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
974
+ }
975
+ }
976
+ }
977
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
978
+ finally {
979
+ try {
980
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
981
+ }
982
+ finally { if (e_1) throw e_1.error; }
983
+ }
984
+ }
985
+ }
986
+ if (words.length === 1) {
987
+ if (tableConfig && tableConfig.columns) {
988
+ try {
989
+ for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
990
+ var column = _f.value;
991
+ if (column.name === words[0] && column.title) {
992
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
993
+ break;
994
+ }
995
+ else if (column.name === words[0] && column.property) {
996
+ words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
997
+ break;
998
+ }
999
+ else if (words[0] === column.name && words[0] === "id" && column.hidden) {
1000
+ break;
1001
+ }
1002
+ else if (words[0] == column.name || words[0] === column.property) {
1003
+ words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
1004
+ }
1005
+ }
1006
+ }
1007
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1008
+ finally {
1009
+ try {
1010
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
1011
+ }
1012
+ finally { if (e_2) throw e_2.error; }
1013
+ }
1014
+ }
1015
+ return words[0];
1016
+ }
1017
+ return words.join(' ');
1018
+ });
1019
+ selectQuery = selectQueryArray.join(',');
1020
+ query.setParam('$select', selectQuery);
1021
+ return query;
1022
+ };
1023
+ /**
1024
+ * Constructs the fetch URL based the query parameters
1025
+ * @param {ClientDataQueryable} query
1026
+ * @return String
1027
+ */
1028
+ BtnExpDirective.prototype.constructURL = function (query) {
1029
+ var baseURL = query.getService().getBase();
1030
+ var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
1031
+ Object.keys(query.getParams()).forEach(function (key, index) {
1032
+ if (index === 0) {
1033
+ url += key + '=' + query.getParams()[key];
1034
+ }
1035
+ else {
1036
+ url += '&' + key + '=' + query.getParams()[key];
1037
+ }
1038
+ });
1039
+ return url;
1040
+ };
1041
+ /**
1042
+ * Constructs the query by setting the parameters of the
1043
+ * advanced table's active filters, sets the necessary headers
1044
+ * and build the select parameter of the query
1045
+ * @param {ClientDataQueryable} query
1046
+ * @param params: The filters of the last query of the activated table
1047
+ * @param tableConfig: The configuration of the activated table
1048
+ * @param {Headers} headers: The headers to append to the query
1049
+ * @return ClientDataQueryable
1050
+ */
1051
+ BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
1052
+ var _query = this.setParams(query, params);
1053
+ _query = this.setHeaders(_query, headers);
1054
+ _query = this.constructQueryParam(_query, tableConfig);
1055
+ return _query;
1056
+ };
1057
+ /**
1058
+ * Fetches and saves the xlsx file
1059
+ * @param {String} url
1060
+ * @param {Headers} serviceHeaders: The headers to append to the query
1061
+ * @param modelName: The model name of the advanced table
1062
+ */
1063
+ BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
1064
+ var _this = this;
1065
+ this._loadingService.showLoading();
1066
+ fetch(encodeURI(url), {
1067
+ headers: serviceHeaders,
1068
+ credentials: 'include'
1069
+ }).then(function (response) {
1070
+ if (response && !response.ok) {
1071
+ throw new ResponseError(response.statusText, response.status);
1072
+ }
1073
+ return response.blob();
1074
+ }).then(function (blob) {
1075
+ var objectUrl = window.URL.createObjectURL(blob);
1076
+ var a = document.createElement('a');
1077
+ document.body.appendChild(a);
1078
+ a.setAttribute('style', 'display: none');
1079
+ a.href = objectUrl;
1080
+ var downloadName = modelName + ".xlsx";
1081
+ a.download = downloadName;
1082
+ // this adds support for IE and MS Edge (up to version 44.19041)
1083
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
1084
+ window.navigator.msSaveOrOpenBlob(blob, downloadName);
1085
+ }
1086
+ else {
1087
+ // for all other browsers
1088
+ a.click();
1089
+ }
1090
+ window.URL.revokeObjectURL(objectUrl);
1091
+ a.remove();
1092
+ _this._loadingService.hideLoading();
1093
+ }).catch(function (err) {
1094
+ _this._loadingService.hideLoading();
1095
+ _this._errorService.showError(err, {
1096
+ continueLink: '.'
1097
+ });
1098
+ });
1099
+ };
1100
+ BtnExpDirective.decorators = [
1101
+ { type: Directive, args: [{
1102
+ selector: '.universis-btn-export'
1103
+ },] }
1104
+ ];
1105
+ /** @nocollapse */
1106
+ BtnExpDirective.ctorParameters = function () { return [
1107
+ { type: ActivatedTableService },
1108
+ { type: AngularDataContext },
1109
+ { type: ConfigurationService },
1110
+ { type: TranslateService },
1111
+ { type: LoadingService },
1112
+ { type: ErrorService }
1113
+ ]; };
1114
+ BtnExpDirective.propDecorators = {
1115
+ clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
1116
+ };
1117
+ return BtnExpDirective;
1118
+ }());
1119
+
822
1120
  // restore jquery import to avoid Cannot call a namespace ('jquery') error
823
1121
  var jQuery = jQuery_;
824
1122
  var DataTablesApi = jQuery.fn.dataTable.Api;
@@ -851,6 +1149,15 @@ var TableTranslationChangeDetector = /** @class */ (function (_super) {
851
1149
  return TableTranslationChangeDetector;
852
1150
  }(ChangeDetectorRef));
853
1151
  var COLUMN_FORMATTERS = new InjectionToken('column.formatters');
1152
+ var ExportLimitExceededError = /** @class */ (function (_super) {
1153
+ __extends(ExportLimitExceededError, _super);
1154
+ function ExportLimitExceededError(message) {
1155
+ var _this = _super.call(this, message) || this;
1156
+ _this.name = 'ExportLimitExceededError';
1157
+ return _this;
1158
+ }
1159
+ return ExportLimitExceededError;
1160
+ }(RangeError));
854
1161
  var ColumnFormatter = /** @class */ (function (_super) {
855
1162
  __extends(ColumnFormatter, _super);
856
1163
  function ColumnFormatter(injector) {
@@ -881,7 +1188,7 @@ function getRandomIdentifier() {
881
1188
  return (Number(String(Math.random()).slice(2))).toString(36);
882
1189
  }
883
1190
  var AdvancedTableComponent = /** @class */ (function () {
884
- function AdvancedTableComponent(_context, _columnFormatters, _activatedRoute, _translateService, _injector, _advancedFilterValueProvider, _element, _template, _loading, _http, _columnSelector) {
1191
+ function AdvancedTableComponent(_context, _columnFormatters, _activatedRoute, _translateService, _injector, _advancedFilterValueProvider, _element, _template, _loading, _http, _columnSelector, _configuration, _exportSpreadsheet, _modalService, _errorService) {
885
1192
  var _this = this;
886
1193
  this._context = _context;
887
1194
  this._columnFormatters = _columnFormatters;
@@ -894,6 +1201,10 @@ var AdvancedTableComponent = /** @class */ (function () {
894
1201
  this._loading = _loading;
895
1202
  this._http = _http;
896
1203
  this._columnSelector = _columnSelector;
1204
+ this._configuration = _configuration;
1205
+ this._exportSpreadsheet = _exportSpreadsheet;
1206
+ this._modalService = _modalService;
1207
+ this._errorService = _errorService;
897
1208
  this._firstLoad = true;
898
1209
  this._showFooter = false;
899
1210
  this._showHeader = true;
@@ -937,6 +1248,7 @@ var AdvancedTableComponent = /** @class */ (function () {
937
1248
  this.customSelect = false;
938
1249
  this.selected = [];
939
1250
  this.unselected = [];
1251
+ this._lastQueryTotalItems = 0;
940
1252
  // initialize translate pipe
941
1253
  this.translator = new TranslatePipe(this._translateService, new TableTranslationChangeDetector());
942
1254
  jQuery.fn.dataTable.ext.classes.sPageButton = 'btn';
@@ -960,6 +1272,13 @@ var AdvancedTableComponent = /** @class */ (function () {
960
1272
  enumerable: true,
961
1273
  configurable: true
962
1274
  });
1275
+ Object.defineProperty(AdvancedTableComponent.prototype, "lastQueryTotalItems", {
1276
+ get: function () {
1277
+ return this._lastQueryTotalItems;
1278
+ },
1279
+ enumerable: true,
1280
+ configurable: true
1281
+ });
963
1282
  Object.defineProperty(AdvancedTableComponent.prototype, "showFooter", {
964
1283
  get: function () {
965
1284
  return this._showFooter;
@@ -1586,6 +1905,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1586
1905
  recordsFiltered: 0,
1587
1906
  data: [],
1588
1907
  };
1908
+ self._lastQueryTotalItems = 0;
1589
1909
  // emit empty data
1590
1910
  self.load.emit(emptyDataSet);
1591
1911
  // return empty data
@@ -1601,7 +1921,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1601
1921
  // get order expression
1602
1922
  var order = aoData[2].value;
1603
1923
  // get skip records param
1604
- var skip = aoData[3].value;
1924
+ var skip$$1 = aoData[3].value;
1605
1925
  // get page size param
1606
1926
  var top = aoData[4].value;
1607
1927
  // get search value
@@ -1610,7 +1930,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1610
1930
  var q = self._query instanceof ClientDataQueryable ? self._query : self._context.model(self.config.model).asQueryable();
1611
1931
  // apply paging params
1612
1932
  if (top) {
1613
- q.take(top).skip(skip);
1933
+ q.take(top).skip(skip$$1);
1614
1934
  }
1615
1935
  // apply order params
1616
1936
  if (order && order.length) {
@@ -1680,6 +2000,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1680
2000
  recordsFiltered: items.total,
1681
2001
  data: items.value,
1682
2002
  };
2003
+ self._lastQueryTotalItems = items.total;
1683
2004
  if (items.total === 0) {
1684
2005
  self.resetEmptyTable();
1685
2006
  }
@@ -1693,6 +2014,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1693
2014
  console.error('TABLES', err);
1694
2015
  // show error
1695
2016
  self.toggleError(err);
2017
+ self._lastQueryTotalItems = 0;
1696
2018
  // by returning empty dataset
1697
2019
  self.load.emit(EMPTY_DATASET);
1698
2020
  return fnCallback(EMPTY_DATASET);
@@ -1705,6 +2027,7 @@ var AdvancedTableComponent = /** @class */ (function () {
1705
2027
  recordsFiltered: items.total,
1706
2028
  data: items.value,
1707
2029
  };
2030
+ self._lastQueryTotalItems = items.total;
1708
2031
  if (items.total === 0) {
1709
2032
  self.resetEmptyTable();
1710
2033
  }
@@ -2088,6 +2411,125 @@ var AdvancedTableComponent = /** @class */ (function () {
2088
2411
  }
2089
2412
  });
2090
2413
  };
2414
+ /**
2415
+ *
2416
+ * @param options to pass an errorHandler callback, if desired
2417
+ * @returns void
2418
+ */
2419
+ AdvancedTableComponent.prototype.exportView = function (options) {
2420
+ return __awaiter(this, void 0, void 0, function () {
2421
+ var exportSettings, exportLimit, totalDisplayedItems, _a, body, header, previousDataState, targetDataState, _b, body, header, err_1;
2422
+ return __generator(this, function (_c) {
2423
+ switch (_c.label) {
2424
+ case 0:
2425
+ _c.trys.push([0, 4, 5, 6]);
2426
+ this._loading.showLoading();
2427
+ // validate query items and config
2428
+ if (!(this._lastQueryTotalItems && this.config)) {
2429
+ // do nothing
2430
+ return [2 /*return*/];
2431
+ }
2432
+ exportSettings = this._configuration.settings;
2433
+ exportLimit = (exportSettings && exportSettings.tables && exportSettings.tables.exportLimit > 0)
2434
+ ? exportSettings.tables.exportLimit : MAX_EXPORT_ITEMS;
2435
+ // and validate it
2436
+ if (this._lastQueryTotalItems > exportLimit) {
2437
+ // call error handler
2438
+ // provide a recognizible error type
2439
+ if (options && options.errorHandler) {
2440
+ options.errorHandler(new ExportLimitExceededError('Export limit exceeded'));
2441
+ return [2 /*return*/];
2442
+ }
2443
+ // or show warning modal and exit
2444
+ this._modalService.showWarningDialog(this._translateService.instant('Tables.ExportList'), this._translateService.instant('Tables.ExportLimitExceeded', { dataLength: this._lastQueryTotalItems, exportLimit: exportLimit }), DIALOG_BUTTONS.Ok);
2445
+ return [2 /*return*/];
2446
+ }
2447
+ totalDisplayedItems = Array.from(this.dataTable.context[0].aiDisplay).length;
2448
+ if (!(totalDisplayedItems === this._lastQueryTotalItems)) return [3 /*break*/, 1];
2449
+ _a = this.getExportableData(), body = _a.body, header = _a.header;
2450
+ // and export them to excel
2451
+ this._exportSpreadsheet.export(body, this._translateService.instant(this.config.title || 'Tables.ExportResults') + ".xlsx", {
2452
+ header: header,
2453
+ skipHeader: false
2454
+ });
2455
+ return [3 /*break*/, 3];
2456
+ case 1:
2457
+ previousDataState = this.dataTable.rows().data().toArray();
2458
+ return [4 /*yield*/, this.lastQuery.take(exportLimit).getItems()];
2459
+ case 2:
2460
+ targetDataState = _c.sent();
2461
+ // change table data on the fly, but do not redraw
2462
+ this.dataTable.clear().rows.add(targetDataState);
2463
+ _b = this.getExportableData(), body = _b.body, header = _b.header;
2464
+ // reset table data
2465
+ this.dataTable.clear().rows.add(previousDataState);
2466
+ // and export target data to excel
2467
+ this._exportSpreadsheet.export(body, this._translateService.instant(this.config.title || 'Tables.ExportResults') + ".xlsx", {
2468
+ header: header,
2469
+ skipHeader: false
2470
+ });
2471
+ _c.label = 3;
2472
+ case 3:
2473
+ // exit
2474
+ return [2 /*return*/];
2475
+ case 4:
2476
+ err_1 = _c.sent();
2477
+ // log error
2478
+ console.error(err_1);
2479
+ // call error handler, if defined
2480
+ if (options && options.errorHandler) {
2481
+ options.errorHandler(err_1);
2482
+ }
2483
+ else {
2484
+ // use default error service
2485
+ this._errorService.showError(err_1, {
2486
+ continueLink: '.'
2487
+ });
2488
+ }
2489
+ return [3 /*break*/, 6];
2490
+ case 5:
2491
+ this._loading.hideLoading();
2492
+ return [7 /*endfinally*/];
2493
+ case 6: return [2 /*return*/];
2494
+ }
2495
+ });
2496
+ });
2497
+ };
2498
+ AdvancedTableComponent.prototype.getExportableData = function () {
2499
+ var _this = this;
2500
+ if (!(this.dataTable && this.dataTable.buttons
2501
+ && typeof this.dataTable.buttons.exportData === 'function' && this.config)) {
2502
+ return { body: [], header: [] };
2503
+ }
2504
+ // fetch exportable excel data
2505
+ var _a = this.dataTable.buttons.exportData(), body = _a.body, header = _a.header;
2506
+ var cleanupIndexes = [];
2507
+ // clean up headers
2508
+ header = header.filter(function (headerItem, index) {
2509
+ // exclude empty headers
2510
+ if (headerItem.trim().length === 0) {
2511
+ cleanupIndexes.push(index);
2512
+ return false;
2513
+ }
2514
+ // find item by title
2515
+ var findItem = _this.config.columns.find(function (column) {
2516
+ return column.title && column.title.length && _this._translateService.instant(column.title) === headerItem;
2517
+ });
2518
+ // exclude hidden columns
2519
+ if (findItem && findItem.hidden === true) {
2520
+ cleanupIndexes.push(index);
2521
+ return false;
2522
+ }
2523
+ return true;
2524
+ });
2525
+ // clean up body
2526
+ body = body.map(function (row) {
2527
+ return row.filter(function (_, rowIndex) {
2528
+ return cleanupIndexes.indexOf(rowIndex) === -1;
2529
+ });
2530
+ });
2531
+ return { body: body, header: header };
2532
+ };
2091
2533
  AdvancedTableComponent.decorators = [
2092
2534
  { type: Component, args: [{
2093
2535
  // tslint:disable-next-line: component-selector
@@ -2109,7 +2551,11 @@ var AdvancedTableComponent = /** @class */ (function () {
2109
2551
  { type: TemplatePipe },
2110
2552
  { type: LoadingService },
2111
2553
  { type: HttpClient },
2112
- { type: ColumnSelectorService }
2554
+ { type: ColumnSelectorService },
2555
+ { type: ConfigurationService },
2556
+ { type: ExportSpreadsheetService },
2557
+ { type: ModalService },
2558
+ { type: ErrorService }
2113
2559
  ]; };
2114
2560
  AdvancedTableComponent.propDecorators = {
2115
2561
  table: [{ type: ViewChild, args: ['table',] }],
@@ -3090,61 +3536,24 @@ var AdvancedTableConfigurationResolver = /** @class */ (function () {
3090
3536
  }());
3091
3537
  var AdvancedSearchConfigurationResolver = /** @class */ (function () {
3092
3538
  function AdvancedSearchConfigurationResolver(_http) {
3093
- this._http = _http;
3094
- }
3095
- AdvancedSearchConfigurationResolver.prototype.resolve = function (route, state) {
3096
- // get list
3097
- var list = route.data.list || route.params.list;
3098
- // get model
3099
- var model = route.data.model || route.params.model;
3100
- // get configuration
3101
- return this._http.get("assets/lists/" + model + "/search." + list + ".json").toPromise();
3102
- };
3103
- AdvancedSearchConfigurationResolver.decorators = [
3104
- { type: Injectable }
3105
- ];
3106
- /** @nocollapse */
3107
- AdvancedSearchConfigurationResolver.ctorParameters = function () { return [
3108
- { type: HttpClient }
3109
- ]; };
3110
- return AdvancedSearchConfigurationResolver;
3111
- }());
3112
-
3113
- var ActivatedTableService = /** @class */ (function () {
3114
- function ActivatedTableService(_router, _activatedRoute) {
3115
- var _this = this;
3116
- this._router = _router;
3117
- this._activatedRoute = _activatedRoute;
3118
- _router.events.forEach(function (event) {
3119
- if (event instanceof NavigationStart) {
3120
- if (_this._activeTable) {
3121
- _this._activeTable = null;
3122
- }
3123
- }
3124
- });
3125
- }
3126
- Object.defineProperty(ActivatedTableService.prototype, "activeTable", {
3127
- get: function () {
3128
- return this._activeTable;
3129
- },
3130
- set: function (tableComponent) {
3131
- this._activeTable = tableComponent;
3132
- },
3133
- enumerable: true,
3134
- configurable: true
3135
- });
3136
- ActivatedTableService.decorators = [
3137
- { type: Injectable, args: [{
3138
- providedIn: 'root'
3139
- },] }
3539
+ this._http = _http;
3540
+ }
3541
+ AdvancedSearchConfigurationResolver.prototype.resolve = function (route, state) {
3542
+ // get list
3543
+ var list = route.data.list || route.params.list;
3544
+ // get model
3545
+ var model = route.data.model || route.params.model;
3546
+ // get configuration
3547
+ return this._http.get("assets/lists/" + model + "/search." + list + ".json").toPromise();
3548
+ };
3549
+ AdvancedSearchConfigurationResolver.decorators = [
3550
+ { type: Injectable }
3140
3551
  ];
3141
3552
  /** @nocollapse */
3142
- ActivatedTableService.ctorParameters = function () { return [
3143
- { type: Router },
3144
- { type: ActivatedRoute }
3553
+ AdvancedSearchConfigurationResolver.ctorParameters = function () { return [
3554
+ { type: HttpClient }
3145
3555
  ]; };
3146
- ActivatedTableService.ngInjectableDef = defineInjectable({ factory: function ActivatedTableService_Factory() { return new ActivatedTableService(inject(Router), inject(ActivatedRoute)); }, token: ActivatedTableService, providedIn: "root" });
3147
- return ActivatedTableService;
3556
+ return AdvancedSearchConfigurationResolver;
3148
3557
  }());
3149
3558
 
3150
3559
  var AdvancedTableSettingsComponent = /** @class */ (function () {
@@ -4058,251 +4467,6 @@ var AdvancedTableEditorDirective = /** @class */ (function () {
4058
4467
  return AdvancedTableEditorDirective;
4059
4468
  }());
4060
4469
 
4061
- var MAX_EXPORT_ITEMS = 500;
4062
- var BtnExpDirective = /** @class */ (function () {
4063
- function BtnExpDirective(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
4064
- this._activatedTable = _activatedTable;
4065
- this._context = _context;
4066
- this._config = _config;
4067
- this._translate = _translate;
4068
- this._loadingService = _loadingService;
4069
- this._errorService = _errorService;
4070
- }
4071
- BtnExpDirective.prototype.clickEvent = function (event) {
4072
- return __awaiter(this, void 0, void 0, function () {
4073
- var lastQuery, tableConfig, serviceHeaders, queryModel, query, queryParams, exportSettings, maxExportItems, url;
4074
- return __generator(this, function (_a) {
4075
- event.preventDefault();
4076
- event.stopPropagation();
4077
- if (this._activatedTable.activeTable) {
4078
- lastQuery = this._activatedTable.activeTable.lastQuery;
4079
- tableConfig = this._activatedTable.activeTable.config;
4080
- serviceHeaders = this._context.getService().getHeaders();
4081
- queryModel = lastQuery.getModel();
4082
- query = this._context.model(queryModel).asQueryable();
4083
- queryParams = lastQuery.getParams();
4084
- query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
4085
- exportSettings = this._config.settings;
4086
- maxExportItems = exportSettings && exportSettings.tables && exportSettings.tables.exportLimit;
4087
- if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
4088
- query.skip(0).take(maxExportItems);
4089
- }
4090
- else {
4091
- query.skip(0).take(MAX_EXPORT_ITEMS);
4092
- }
4093
- url = this.constructURL(query);
4094
- this.downloadFile(url, query.getService().getHeaders(), query.getModel());
4095
- }
4096
- return [2 /*return*/];
4097
- });
4098
- });
4099
- };
4100
- /**
4101
- * Sets the parameters to the query based on
4102
- * the active filters of the activated table
4103
- * @param {ClientDataQueryable} query
4104
- * @param params: The filters of the last query of the activated table
4105
- * @return ClientDataQueryable
4106
- */
4107
- BtnExpDirective.prototype.setParams = function (query, params) {
4108
- if (params && typeof params === 'object') {
4109
- Object.keys(params).forEach(function (key) {
4110
- query.setParam(key, params[key]);
4111
- });
4112
- }
4113
- return query;
4114
- };
4115
- /**
4116
- * Sets the headers to the query based on
4117
- * the default headers of the DataContext
4118
- * and appending the accept header to get
4119
- * an xlsx file from the API
4120
- * @param {ClientDataQueryable} query
4121
- * @param {Headers} headers: The headers to append to the query
4122
- * @return ClientDataQueryable
4123
- */
4124
- BtnExpDirective.prototype.setHeaders = function (query, headers) {
4125
- Object.keys(headers).forEach(function (key) {
4126
- if (headers.hasOwnProperty(key)) {
4127
- query.getService().setHeader(key, headers[key]);
4128
- }
4129
- });
4130
- // sets a header to accept xlsx files
4131
- query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
4132
- return query;
4133
- };
4134
- /**
4135
- * Constructs the select parameter of the
4136
- * ClientDataQuery by replacing the target name
4137
- * of the field based on the localized translation
4138
- * of that property on the advanced tabled
4139
- * @param {ClientDataQueryable} query
4140
- * @param tableConfig: The configuration of the activated table
4141
- * @return ClientDataQueryable
4142
- */
4143
- BtnExpDirective.prototype.constructQueryParam = function (query, tableConfig) {
4144
- var _this = this;
4145
- var selectQuery = query.getParams().$select;
4146
- var selectQueryArray = selectQuery.split(',');
4147
- selectQueryArray = selectQueryArray.map(function (select$$1) {
4148
- var e_1, _a, e_2, _b;
4149
- var words = select$$1.split(' ');
4150
- if (words.length === 3) {
4151
- if (tableConfig && tableConfig.columns) {
4152
- try {
4153
- for (var _c = __values(tableConfig.columns), _d = _c.next(); !_d.done; _d = _c.next()) {
4154
- var column = _d.value;
4155
- if (column.property === words[2] && column.title) {
4156
- words[2] = "\"" + _this._translate.instant(column.title) + "\"";
4157
- }
4158
- else if (column.property === words[2]) {
4159
- words[2] = "\"" + _this._translate.instant(words[2]) + "\"";
4160
- }
4161
- }
4162
- }
4163
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
4164
- finally {
4165
- try {
4166
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
4167
- }
4168
- finally { if (e_1) throw e_1.error; }
4169
- }
4170
- }
4171
- }
4172
- if (words.length === 1) {
4173
- if (tableConfig && tableConfig.columns) {
4174
- try {
4175
- for (var _e = __values(tableConfig.columns), _f = _e.next(); !_f.done; _f = _e.next()) {
4176
- var column = _f.value;
4177
- if (column.name === words[0] && column.title) {
4178
- words[0] = words[0] + " as \"" + _this._translate.instant(column.title) + "\"";
4179
- break;
4180
- }
4181
- else if (column.name === words[0] && column.property) {
4182
- words[0] = words[0] + " as \"" + _this._translate.instant(column.property) + "\"";
4183
- break;
4184
- }
4185
- else if (words[0] === column.name && words[0] === "id" && column.hidden) {
4186
- break;
4187
- }
4188
- else if (words[0] == column.name || words[0] === column.property) {
4189
- words[0] = words[0] + " as \"" + _this._translate.instant(words[0]) + "\"";
4190
- }
4191
- }
4192
- }
4193
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
4194
- finally {
4195
- try {
4196
- if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
4197
- }
4198
- finally { if (e_2) throw e_2.error; }
4199
- }
4200
- }
4201
- return words[0];
4202
- }
4203
- return words.join(' ');
4204
- });
4205
- selectQuery = selectQueryArray.join(',');
4206
- query.setParam('$select', selectQuery);
4207
- return query;
4208
- };
4209
- /**
4210
- * Constructs the fetch URL based the query parameters
4211
- * @param {ClientDataQueryable} query
4212
- * @return String
4213
- */
4214
- BtnExpDirective.prototype.constructURL = function (query) {
4215
- var baseURL = query.getService().getBase();
4216
- var url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
4217
- Object.keys(query.getParams()).forEach(function (key, index) {
4218
- if (index === 0) {
4219
- url += key + '=' + query.getParams()[key];
4220
- }
4221
- else {
4222
- url += '&' + key + '=' + query.getParams()[key];
4223
- }
4224
- });
4225
- return url;
4226
- };
4227
- /**
4228
- * Constructs the query by setting the parameters of the
4229
- * advanced table's active filters, sets the necessary headers
4230
- * and build the select parameter of the query
4231
- * @param {ClientDataQueryable} query
4232
- * @param params: The filters of the last query of the activated table
4233
- * @param tableConfig: The configuration of the activated table
4234
- * @param {Headers} headers: The headers to append to the query
4235
- * @return ClientDataQueryable
4236
- */
4237
- BtnExpDirective.prototype.constructQuery = function (query, params, tableConfig, headers) {
4238
- var _query = this.setParams(query, params);
4239
- _query = this.setHeaders(_query, headers);
4240
- _query = this.constructQueryParam(_query, tableConfig);
4241
- return _query;
4242
- };
4243
- /**
4244
- * Fetches and saves the xlsx file
4245
- * @param {String} url
4246
- * @param {Headers} serviceHeaders: The headers to append to the query
4247
- * @param modelName: The model name of the advanced table
4248
- */
4249
- BtnExpDirective.prototype.downloadFile = function (url, serviceHeaders, modelName) {
4250
- var _this = this;
4251
- this._loadingService.showLoading();
4252
- fetch(encodeURI(url), {
4253
- headers: serviceHeaders,
4254
- credentials: 'include'
4255
- }).then(function (response) {
4256
- if (response && !response.ok) {
4257
- throw new ResponseError(response.statusText, response.status);
4258
- }
4259
- return response.blob();
4260
- }).then(function (blob) {
4261
- var objectUrl = window.URL.createObjectURL(blob);
4262
- var a = document.createElement('a');
4263
- document.body.appendChild(a);
4264
- a.setAttribute('style', 'display: none');
4265
- a.href = objectUrl;
4266
- var downloadName = modelName + ".xlsx";
4267
- a.download = downloadName;
4268
- // this adds support for IE and MS Edge (up to version 44.19041)
4269
- if (window.navigator && window.navigator.msSaveOrOpenBlob) {
4270
- window.navigator.msSaveOrOpenBlob(blob, downloadName);
4271
- }
4272
- else {
4273
- // for all other browsers
4274
- a.click();
4275
- }
4276
- window.URL.revokeObjectURL(objectUrl);
4277
- a.remove();
4278
- _this._loadingService.hideLoading();
4279
- }).catch(function (err) {
4280
- _this._loadingService.hideLoading();
4281
- _this._errorService.showError(err, {
4282
- continueLink: '.'
4283
- });
4284
- });
4285
- };
4286
- BtnExpDirective.decorators = [
4287
- { type: Directive, args: [{
4288
- selector: '.universis-btn-export'
4289
- },] }
4290
- ];
4291
- /** @nocollapse */
4292
- BtnExpDirective.ctorParameters = function () { return [
4293
- { type: ActivatedTableService },
4294
- { type: AngularDataContext },
4295
- { type: ConfigurationService },
4296
- { type: TranslateService },
4297
- { type: LoadingService },
4298
- { type: ErrorService }
4299
- ]; };
4300
- BtnExpDirective.propDecorators = {
4301
- clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
4302
- };
4303
- return BtnExpDirective;
4304
- }());
4305
-
4306
4470
  var AdvancedAggregatorService = /** @class */ (function () {
4307
4471
  function AdvancedAggregatorService(_context, _template) {
4308
4472
  this._context = _context;
@@ -4865,6 +5029,8 @@ var ParseTitlePipe = /** @class */ (function () {
4865
5029
  return ParseTitlePipe;
4866
5030
  }());
4867
5031
 
5032
+ // tslint:disable: quotemark
5033
+ // tslint:disable: max-line-length
4868
5034
  var TABLES_EL = {
4869
5035
  "Tables": {
4870
5036
  "Export": "Εξαγωγή",
@@ -4948,7 +5114,10 @@ var TABLES_EL = {
4948
5114
  "DataError": {
4949
5115
  "Title": "Σφάλμα κατά την παραλαβή των δεδομένων",
4950
5116
  "Message": "Συνέβη σφάλμα κατά την παραλαβή των δεδομένων. Προσπαθήστε ξανά ή τροποποιήστε τα στοιχεία αναζήτησης."
4951
- }
5117
+ },
5118
+ "ExportList": "Εξαγωγή λίστας",
5119
+ "ExportLimitExceeded": "Το πλήθος των στοιχείων προς εξαγωγή ({{dataLength}}) ξεπερνάει το μέγιστο επιτρεπτό ({{exportLimit}}). Παρακαλούμε προσαρμόστε τα φίλτρα της αναζήτησης και προσπαθήστε ξανά.",
5120
+ "ExportResults": "Δεδομένα λίστας"
4952
5121
  },
4953
5122
  "TrueFalse": {
4954
5123
  "long": {
@@ -4989,6 +5158,8 @@ var TABLES_EL = {
4989
5158
  }
4990
5159
  };
4991
5160
 
5161
+ // tslint:disable: quotemark
5162
+ // tslint:disable: max-line-length
4992
5163
  var TABLES_EN = {
4993
5164
  "Tables": {
4994
5165
  "Export": "Export",
@@ -5071,7 +5242,10 @@ var TABLES_EN = {
5071
5242
  "DataError": {
5072
5243
  "Title": "Error while getting data",
5073
5244
  "Message": "An error occurred while getting data. Please try again or change your criteria."
5074
- }
5245
+ },
5246
+ "ExportList": "Export list",
5247
+ "ExportLimitExceeded": "The number of items that are to be exported ({{dataLength}}) exceeds the export limit ({{exportLimit}}). Please apply more specific filters to the search.",
5248
+ "ExportResults": "Exported list"
5075
5249
  },
5076
5250
  "TrueFalse": {
5077
5251
  "long": {
@@ -5502,6 +5676,6 @@ var TablesModule = /** @class */ (function () {
5502
5676
  * Generated bundle index. Do not edit.
5503
5677
  */
5504
5678
 
5505
- export { AdvancedSearchState as ɵa, AdvancedTableState as ɵc, AdvancedSearchRouterState as ɵd, 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, ɵ0, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ActivatedTableService, ColumnSelectorService, ColumnSelectorComponent, initialState, tableInitialState, tableReducer, tableReducers, featureName, getTablesState, selectTable };
5679
+ export { AdvancedSearchState as ɵa, AdvancedTableState as ɵc, AdvancedSearchRouterState as ɵd, AdvancedListComponent, AdvancedRowActionComponent, AdvancedSearchFormComponent, AdvancedSelectComponent, AdvancedSelectService, AdvancedTableConfigurationResolver, AdvancedSearchConfigurationResolver, AdvancedColumnFormatter, NestedPropertyFormatter, ButtonFormatter, LinkFormatter, ActionLinkFormatter, ActionButtonFormatter, ActionSplitButtonFormatter, SelectRowFormatter, TemplateFormatter, TrueFalseFormatter, TranslationFormatter, DateTimeFormatter, NgClassFormatter, LanguageFormatter, COLUMN_FORMATTERS, ExportLimitExceededError, AdvancedTableConfiguration, AdvancedTableComponent, ɵ0, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, MAX_EXPORT_ITEMS, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule, ActivatedTableService, ColumnSelectorService, ColumnSelectorComponent, initialState, tableInitialState, tableReducer, tableReducers, featureName, getTablesState, selectTable };
5506
5680
 
5507
5681
  //# sourceMappingURL=universis-ngx-tables.js.map