@universis/ngx-tables 0.7.30 → 0.8.1
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.
- package/bundles/universis-ngx-tables.umd.js +527 -315
- package/bundles/universis-ngx-tables.umd.js.map +1 -1
- package/bundles/universis-ngx-tables.umd.min.js +1 -1
- package/bundles/universis-ngx-tables.umd.min.js.map +1 -1
- package/esm2015/lib/components/advanced-table/advanced-table.component.js +206 -7
- package/esm2015/lib/directives/btnexp.directive.js +9 -8
- package/esm2015/lib/i18n/tables.el.js +11 -2
- package/esm2015/lib/i18n/tables.en.js +11 -2
- package/esm5/lib/components/advanced-table/advanced-table.component.js +200 -8
- package/esm5/lib/directives/btnexp.directive.js +20 -17
- package/esm5/lib/i18n/tables.el.js +11 -2
- package/esm5/lib/i18n/tables.en.js +11 -2
- package/fesm2015/universis-ngx-tables.js +482 -267
- package/fesm2015/universis-ngx-tables.js.map +1 -1
- package/fesm5/universis-ngx-tables.js +522 -312
- package/fesm5/universis-ngx-tables.js.map +1 -1
- package/lib/components/advanced-table/advanced-table.component.d.ts +27 -2
- package/lib/directives/btnexp.directive.d.ts +6 -0
- package/lib/i18n/tables.el.d.ts +7 -0
- package/lib/i18n/tables.en.d.ts +7 -0
- package/package.json +4 -4
- package/universis-ngx-tables.metadata.json +1 -1
|
@@ -3,16 +3,17 @@ 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 {
|
|
9
|
+
import { ResponseError, ClientDataQueryable, TextUtils } from '@themost/client';
|
|
9
10
|
import { BehaviorSubject } from 'rxjs';
|
|
10
11
|
import { AngularDataContext } from '@themost/angular';
|
|
11
12
|
import { __awaiter } from 'tslib';
|
|
12
13
|
import { DatePipe, CommonModule } from '@angular/common';
|
|
13
14
|
import { TranslateService, TranslatePipe, TranslateModule } from '@ngx-translate/core';
|
|
14
15
|
import { FormControl, FormArray, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
15
|
-
import { TemplatePipe, ModalService,
|
|
16
|
+
import { TemplatePipe, ModalService, ConfigurationService, ErrorService, LoadingService, DIALOG_BUTTONS, ExportSpreadsheetService, UserActivityService, ToastService, AppEventService, UserStorageService, SharedModule } from '@universis/common';
|
|
16
17
|
import { RouterModalOkCancel, RouterModalModule } from '@universis/common/routing';
|
|
17
18
|
import { ServiceUrlPreProcessor, TranslatePreProcessor, AdvancedFormsModule } from '@universis/forms';
|
|
18
19
|
import { FormioModule } from 'angular-formio';
|
|
@@ -20,7 +21,7 @@ import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
|
|
|
20
21
|
import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
|
|
21
22
|
import { GroupByPipe, NgPipesModule } from 'ngx-pipes';
|
|
22
23
|
import { template, at, cloneDeep } from 'lodash';
|
|
23
|
-
import { Injectable, Directive, Optional, Input, Output, EventEmitter, Pipe, Component, ViewChild, ViewEncapsulation,
|
|
24
|
+
import { Injectable, Directive, Optional, Input, Output, EventEmitter, Pipe, Component, ViewChild, ViewEncapsulation, ElementRef, ChangeDetectorRef, NgModule, CUSTOM_ELEMENTS_SCHEMA, defineInjectable, inject, HostListener, 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
27
|
import { first, filter } from 'rxjs/operators';
|
|
@@ -704,6 +705,258 @@ ColumnSelectorService.ctorParameters = () => [
|
|
|
704
705
|
{ type: ModalService }
|
|
705
706
|
];
|
|
706
707
|
|
|
708
|
+
class ActivatedTableService {
|
|
709
|
+
constructor(_router, _activatedRoute) {
|
|
710
|
+
this._router = _router;
|
|
711
|
+
this._activatedRoute = _activatedRoute;
|
|
712
|
+
_router.events.forEach((event) => {
|
|
713
|
+
if (event instanceof NavigationStart) {
|
|
714
|
+
if (this._activeTable) {
|
|
715
|
+
this._activeTable = null;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
get activeTable() {
|
|
721
|
+
return this._activeTable;
|
|
722
|
+
}
|
|
723
|
+
set activeTable(tableComponent) {
|
|
724
|
+
this._activeTable = tableComponent;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
ActivatedTableService.decorators = [
|
|
728
|
+
{ type: Injectable, args: [{
|
|
729
|
+
providedIn: 'root'
|
|
730
|
+
},] }
|
|
731
|
+
];
|
|
732
|
+
/** @nocollapse */
|
|
733
|
+
ActivatedTableService.ctorParameters = () => [
|
|
734
|
+
{ type: Router },
|
|
735
|
+
{ type: ActivatedRoute }
|
|
736
|
+
];
|
|
737
|
+
ActivatedTableService.ngInjectableDef = defineInjectable({ factory: function ActivatedTableService_Factory() { return new ActivatedTableService(inject(Router), inject(ActivatedRoute)); }, token: ActivatedTableService, providedIn: "root" });
|
|
738
|
+
|
|
739
|
+
const MAX_EXPORT_ITEMS = 500;
|
|
740
|
+
class BtnExpDirective {
|
|
741
|
+
constructor(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
|
|
742
|
+
this._activatedTable = _activatedTable;
|
|
743
|
+
this._context = _context;
|
|
744
|
+
this._config = _config;
|
|
745
|
+
this._translate = _translate;
|
|
746
|
+
this._loadingService = _loadingService;
|
|
747
|
+
this._errorService = _errorService;
|
|
748
|
+
}
|
|
749
|
+
clickEvent(event) {
|
|
750
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
751
|
+
event.preventDefault();
|
|
752
|
+
event.stopPropagation();
|
|
753
|
+
if (this._activatedTable.activeTable) {
|
|
754
|
+
return this._activatedTable.activeTable.exportView();
|
|
755
|
+
/*
|
|
756
|
+
const lastQuery = this._activatedTable.activeTable.lastQuery;
|
|
757
|
+
const tableConfig = this._activatedTable.activeTable.config;
|
|
758
|
+
const serviceHeaders = this._context.getService().getHeaders();
|
|
759
|
+
const queryModel = lastQuery.getModel();
|
|
760
|
+
let query = this._context.model(queryModel).asQueryable();
|
|
761
|
+
const queryParams = lastQuery.getParams();
|
|
762
|
+
query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
|
|
763
|
+
// get export settings
|
|
764
|
+
const exportSettings = this._config.settings as ExportLimitConfiguration;
|
|
765
|
+
// get export limit
|
|
766
|
+
const maxExportItems = exportSettings && exportSettings.tables && exportSettings.tables.exportLimit;
|
|
767
|
+
if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
|
|
768
|
+
query.skip(0).take(maxExportItems);
|
|
769
|
+
} else {
|
|
770
|
+
query.skip(0).take(MAX_EXPORT_ITEMS);
|
|
771
|
+
}
|
|
772
|
+
// This constructs the URI based on the way @themost does
|
|
773
|
+
const url = this.constructURL(query);
|
|
774
|
+
this.downloadFile(url, query.getService().getHeaders(), query.getModel()); */
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Sets the parameters to the query based on
|
|
780
|
+
* the active filters of the activated table
|
|
781
|
+
* @param {ClientDataQueryable} query
|
|
782
|
+
* @param params: The filters of the last query of the activated table
|
|
783
|
+
* @return ClientDataQueryable
|
|
784
|
+
*/
|
|
785
|
+
setParams(query, params) {
|
|
786
|
+
if (params && typeof params === 'object') {
|
|
787
|
+
Object.keys(params).forEach((key) => {
|
|
788
|
+
query.setParam(key, params[key]);
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
return query;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Sets the headers to the query based on
|
|
795
|
+
* the default headers of the DataContext
|
|
796
|
+
* and appending the accept header to get
|
|
797
|
+
* an xlsx file from the API
|
|
798
|
+
* @param {ClientDataQueryable} query
|
|
799
|
+
* @param {Headers} headers: The headers to append to the query
|
|
800
|
+
* @return ClientDataQueryable
|
|
801
|
+
*/
|
|
802
|
+
setHeaders(query, headers) {
|
|
803
|
+
Object.keys(headers).forEach((key) => {
|
|
804
|
+
if (headers.hasOwnProperty(key)) {
|
|
805
|
+
query.getService().setHeader(key, headers[key]);
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
// sets a header to accept xlsx files
|
|
809
|
+
query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
810
|
+
return query;
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Constructs the select parameter of the
|
|
814
|
+
* ClientDataQuery by replacing the target name
|
|
815
|
+
* of the field based on the localized translation
|
|
816
|
+
* of that property on the advanced tabled
|
|
817
|
+
* @param {ClientDataQueryable} query
|
|
818
|
+
* @param tableConfig: The configuration of the activated table
|
|
819
|
+
* @return ClientDataQueryable
|
|
820
|
+
*/
|
|
821
|
+
constructQueryParam(query, tableConfig) {
|
|
822
|
+
let selectQuery = query.getParams().$select;
|
|
823
|
+
let selectQueryArray = selectQuery.split(',');
|
|
824
|
+
selectQueryArray = selectQueryArray.map((select$$1) => {
|
|
825
|
+
const words = select$$1.split(' ');
|
|
826
|
+
if (words.length === 3) {
|
|
827
|
+
if (tableConfig && tableConfig.columns) {
|
|
828
|
+
for (const column of tableConfig.columns) {
|
|
829
|
+
if (column.property === words[2] && column.title) {
|
|
830
|
+
words[2] = `"${this._translate.instant(column.title)}"`;
|
|
831
|
+
}
|
|
832
|
+
else if (column.property === words[2]) {
|
|
833
|
+
words[2] = `"${this._translate.instant(words[2])}"`;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
if (words.length === 1) {
|
|
839
|
+
if (tableConfig && tableConfig.columns) {
|
|
840
|
+
for (const column of tableConfig.columns) {
|
|
841
|
+
if (column.name === words[0] && column.title) {
|
|
842
|
+
words[0] = `${words[0]} as "${this._translate.instant(column.title)}"`;
|
|
843
|
+
break;
|
|
844
|
+
}
|
|
845
|
+
else if (column.name === words[0] && column.property) {
|
|
846
|
+
words[0] = `${words[0]} as "${this._translate.instant(column.property)}"`;
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
else if (words[0] === column.name && words[0] === "id" && column.hidden) {
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
else if (words[0] == column.name || words[0] === column.property) {
|
|
853
|
+
words[0] = `${words[0]} as "${this._translate.instant(words[0])}"`;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return words[0];
|
|
858
|
+
}
|
|
859
|
+
return words.join(' ');
|
|
860
|
+
});
|
|
861
|
+
selectQuery = selectQueryArray.join(',');
|
|
862
|
+
query.setParam('$select', selectQuery);
|
|
863
|
+
return query;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Constructs the fetch URL based the query parameters
|
|
867
|
+
* @param {ClientDataQueryable} query
|
|
868
|
+
* @return String
|
|
869
|
+
*/
|
|
870
|
+
constructURL(query) {
|
|
871
|
+
const baseURL = query.getService().getBase();
|
|
872
|
+
let url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
|
|
873
|
+
Object.keys(query.getParams()).forEach((key, index) => {
|
|
874
|
+
if (index === 0) {
|
|
875
|
+
url += key + '=' + query.getParams()[key];
|
|
876
|
+
}
|
|
877
|
+
else {
|
|
878
|
+
url += '&' + key + '=' + query.getParams()[key];
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
return url;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Constructs the query by setting the parameters of the
|
|
885
|
+
* advanced table's active filters, sets the necessary headers
|
|
886
|
+
* and build the select parameter of the query
|
|
887
|
+
* @param {ClientDataQueryable} query
|
|
888
|
+
* @param params: The filters of the last query of the activated table
|
|
889
|
+
* @param tableConfig: The configuration of the activated table
|
|
890
|
+
* @param {Headers} headers: The headers to append to the query
|
|
891
|
+
* @return ClientDataQueryable
|
|
892
|
+
*/
|
|
893
|
+
constructQuery(query, params, tableConfig, headers) {
|
|
894
|
+
let _query = this.setParams(query, params);
|
|
895
|
+
_query = this.setHeaders(_query, headers);
|
|
896
|
+
_query = this.constructQueryParam(_query, tableConfig);
|
|
897
|
+
return _query;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Fetches and saves the xlsx file
|
|
901
|
+
* @param {String} url
|
|
902
|
+
* @param {Headers} serviceHeaders: The headers to append to the query
|
|
903
|
+
* @param modelName: The model name of the advanced table
|
|
904
|
+
*/
|
|
905
|
+
downloadFile(url, serviceHeaders, modelName) {
|
|
906
|
+
this._loadingService.showLoading();
|
|
907
|
+
fetch(encodeURI(url), {
|
|
908
|
+
headers: serviceHeaders,
|
|
909
|
+
credentials: 'include'
|
|
910
|
+
}).then(response => {
|
|
911
|
+
if (response && !response.ok) {
|
|
912
|
+
throw new ResponseError(response.statusText, response.status);
|
|
913
|
+
}
|
|
914
|
+
return response.blob();
|
|
915
|
+
}).then(blob => {
|
|
916
|
+
const objectUrl = window.URL.createObjectURL(blob);
|
|
917
|
+
const a = document.createElement('a');
|
|
918
|
+
document.body.appendChild(a);
|
|
919
|
+
a.setAttribute('style', 'display: none');
|
|
920
|
+
a.href = objectUrl;
|
|
921
|
+
const downloadName = `${modelName}.xlsx`;
|
|
922
|
+
a.download = downloadName;
|
|
923
|
+
// this adds support for IE and MS Edge (up to version 44.19041)
|
|
924
|
+
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
|
925
|
+
window.navigator.msSaveOrOpenBlob(blob, downloadName);
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
// for all other browsers
|
|
929
|
+
a.click();
|
|
930
|
+
}
|
|
931
|
+
window.URL.revokeObjectURL(objectUrl);
|
|
932
|
+
a.remove();
|
|
933
|
+
this._loadingService.hideLoading();
|
|
934
|
+
}).catch(err => {
|
|
935
|
+
this._loadingService.hideLoading();
|
|
936
|
+
this._errorService.showError(err, {
|
|
937
|
+
continueLink: '.'
|
|
938
|
+
});
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
BtnExpDirective.decorators = [
|
|
943
|
+
{ type: Directive, args: [{
|
|
944
|
+
selector: '.universis-btn-export'
|
|
945
|
+
},] }
|
|
946
|
+
];
|
|
947
|
+
/** @nocollapse */
|
|
948
|
+
BtnExpDirective.ctorParameters = () => [
|
|
949
|
+
{ type: ActivatedTableService },
|
|
950
|
+
{ type: AngularDataContext },
|
|
951
|
+
{ type: ConfigurationService },
|
|
952
|
+
{ type: TranslateService },
|
|
953
|
+
{ type: LoadingService },
|
|
954
|
+
{ type: ErrorService }
|
|
955
|
+
];
|
|
956
|
+
BtnExpDirective.propDecorators = {
|
|
957
|
+
clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
|
|
958
|
+
};
|
|
959
|
+
|
|
707
960
|
// restore jquery import to avoid Cannot call a namespace ('jquery') error
|
|
708
961
|
const jQuery = jQuery_;
|
|
709
962
|
const DataTablesApi = jQuery.fn.dataTable.Api;
|
|
@@ -712,6 +965,12 @@ DataTablesApi.register('processing()', function (show) {
|
|
|
712
965
|
ctx.oApi._fnProcessingDisplay(ctx, show);
|
|
713
966
|
});
|
|
714
967
|
});
|
|
968
|
+
const ɵ0 = [];
|
|
969
|
+
const EMPTY_DATASET = {
|
|
970
|
+
recordsTotal: 0,
|
|
971
|
+
recordsFiltered: 0,
|
|
972
|
+
data: ɵ0,
|
|
973
|
+
};
|
|
715
974
|
class TableTranslationChangeDetector extends ChangeDetectorRef {
|
|
716
975
|
checkNoChanges() {
|
|
717
976
|
}
|
|
@@ -725,6 +984,12 @@ class TableTranslationChangeDetector extends ChangeDetectorRef {
|
|
|
725
984
|
}
|
|
726
985
|
}
|
|
727
986
|
let COLUMN_FORMATTERS = new InjectionToken('column.formatters');
|
|
987
|
+
class ExportLimitExceededError extends RangeError {
|
|
988
|
+
constructor(message) {
|
|
989
|
+
super(message);
|
|
990
|
+
this.name = 'ExportLimitExceededError';
|
|
991
|
+
}
|
|
992
|
+
}
|
|
728
993
|
class ColumnFormatter extends AdvancedColumnFormatter {
|
|
729
994
|
constructor(injector) {
|
|
730
995
|
super();
|
|
@@ -749,7 +1014,7 @@ function getRandomIdentifier() {
|
|
|
749
1014
|
return (Number(String(Math.random()).slice(2))).toString(36);
|
|
750
1015
|
}
|
|
751
1016
|
class AdvancedTableComponent {
|
|
752
|
-
constructor(_context, _columnFormatters, _activatedRoute, _translateService, _injector, _advancedFilterValueProvider, _element, _template, _loading, _http, _columnSelector) {
|
|
1017
|
+
constructor(_context, _columnFormatters, _activatedRoute, _translateService, _injector, _advancedFilterValueProvider, _element, _template, _loading, _http, _columnSelector, _configuration, _exportSpreadsheet, _modalService, _errorService) {
|
|
753
1018
|
this._context = _context;
|
|
754
1019
|
this._columnFormatters = _columnFormatters;
|
|
755
1020
|
this._activatedRoute = _activatedRoute;
|
|
@@ -761,6 +1026,10 @@ class AdvancedTableComponent {
|
|
|
761
1026
|
this._loading = _loading;
|
|
762
1027
|
this._http = _http;
|
|
763
1028
|
this._columnSelector = _columnSelector;
|
|
1029
|
+
this._configuration = _configuration;
|
|
1030
|
+
this._exportSpreadsheet = _exportSpreadsheet;
|
|
1031
|
+
this._modalService = _modalService;
|
|
1032
|
+
this._errorService = _errorService;
|
|
764
1033
|
this._firstLoad = true;
|
|
765
1034
|
this._showFooter = false;
|
|
766
1035
|
this._showHeader = true;
|
|
@@ -804,6 +1073,7 @@ class AdvancedTableComponent {
|
|
|
804
1073
|
this.customSelect = false;
|
|
805
1074
|
this.selected = [];
|
|
806
1075
|
this.unselected = [];
|
|
1076
|
+
this._lastQueryTotalItems = 0;
|
|
807
1077
|
// initialize translate pipe
|
|
808
1078
|
this.translator = new TranslatePipe(this._translateService, new TableTranslationChangeDetector());
|
|
809
1079
|
jQuery.fn.dataTable.ext.classes.sPageButton = 'btn';
|
|
@@ -823,6 +1093,9 @@ class AdvancedTableComponent {
|
|
|
823
1093
|
get config() {
|
|
824
1094
|
return this._config;
|
|
825
1095
|
}
|
|
1096
|
+
get lastQueryTotalItems() {
|
|
1097
|
+
return this._lastQueryTotalItems;
|
|
1098
|
+
}
|
|
826
1099
|
/**
|
|
827
1100
|
* Indicates whether table footer will be visible or not
|
|
828
1101
|
*/
|
|
@@ -1431,12 +1704,15 @@ class AdvancedTableComponent {
|
|
|
1431
1704
|
recordsFiltered: 0,
|
|
1432
1705
|
data: [],
|
|
1433
1706
|
};
|
|
1707
|
+
self._lastQueryTotalItems = 0;
|
|
1434
1708
|
// emit empty data
|
|
1435
1709
|
self.load.emit(emptyDataSet);
|
|
1436
1710
|
// return empty data
|
|
1437
1711
|
return fnCallback(emptyDataSet);
|
|
1438
1712
|
}
|
|
1439
1713
|
}
|
|
1714
|
+
// reset error
|
|
1715
|
+
self.toggleError();
|
|
1440
1716
|
// get activated route params
|
|
1441
1717
|
const queryParams = self._activatedRoute.snapshot.queryParams;
|
|
1442
1718
|
// get columns
|
|
@@ -1517,12 +1793,13 @@ class AdvancedTableComponent {
|
|
|
1517
1793
|
q.filter(expressions.join(' and '));
|
|
1518
1794
|
}
|
|
1519
1795
|
self.lastQueryParams = q.getParams();
|
|
1520
|
-
q.getList().then((items) => {
|
|
1796
|
+
return q.getList().then((items) => {
|
|
1521
1797
|
const dataSet = {
|
|
1522
1798
|
recordsTotal: items.total,
|
|
1523
1799
|
recordsFiltered: items.total,
|
|
1524
1800
|
data: items.value,
|
|
1525
1801
|
};
|
|
1802
|
+
self._lastQueryTotalItems = items.total;
|
|
1526
1803
|
if (items.total === 0) {
|
|
1527
1804
|
self.resetEmptyTable();
|
|
1528
1805
|
}
|
|
@@ -1532,7 +1809,14 @@ class AdvancedTableComponent {
|
|
|
1532
1809
|
return fnCallback(dataSet);
|
|
1533
1810
|
});
|
|
1534
1811
|
}).catch((err) => {
|
|
1812
|
+
// log error to console
|
|
1535
1813
|
console.error('TABLES', err);
|
|
1814
|
+
// show error
|
|
1815
|
+
self.toggleError(err);
|
|
1816
|
+
self._lastQueryTotalItems = 0;
|
|
1817
|
+
// by returning empty dataset
|
|
1818
|
+
self.load.emit(EMPTY_DATASET);
|
|
1819
|
+
return fnCallback(EMPTY_DATASET);
|
|
1536
1820
|
});
|
|
1537
1821
|
}
|
|
1538
1822
|
self.lastQueryParams = q.getParams();
|
|
@@ -1542,6 +1826,7 @@ class AdvancedTableComponent {
|
|
|
1542
1826
|
recordsFiltered: items.total,
|
|
1543
1827
|
data: items.value,
|
|
1544
1828
|
};
|
|
1829
|
+
self._lastQueryTotalItems = items.total;
|
|
1545
1830
|
if (items.total === 0) {
|
|
1546
1831
|
self.resetEmptyTable();
|
|
1547
1832
|
}
|
|
@@ -1550,7 +1835,13 @@ class AdvancedTableComponent {
|
|
|
1550
1835
|
// return data
|
|
1551
1836
|
return fnCallback(dataSet);
|
|
1552
1837
|
}).catch((err) => {
|
|
1838
|
+
// log error to console
|
|
1553
1839
|
console.error('TABLES', err);
|
|
1840
|
+
// show error
|
|
1841
|
+
self.toggleError(err);
|
|
1842
|
+
// by returning empty dataset
|
|
1843
|
+
self.load.emit(EMPTY_DATASET);
|
|
1844
|
+
return fnCallback(EMPTY_DATASET);
|
|
1554
1845
|
});
|
|
1555
1846
|
},
|
|
1556
1847
|
language: Object.assign({}, self.translator.transform('Tables.DataTable'), { emptyTable: ' ' }),
|
|
@@ -1777,9 +2068,28 @@ class AdvancedTableComponent {
|
|
|
1777
2068
|
this.dataTable.context[0].oLanguage.sZeroRecords = this.emptyTable.nativeElement.innerHTML;
|
|
1778
2069
|
}
|
|
1779
2070
|
}
|
|
2071
|
+
toggleError(err) {
|
|
2072
|
+
if (this.dataTable && this.dataTable.context[0]) {
|
|
2073
|
+
const innerMessage = this.errorTemplate.nativeElement.getElementsByTagName('small').item(0);
|
|
2074
|
+
if (err) {
|
|
2075
|
+
this.lastError = err;
|
|
2076
|
+
if (innerMessage) {
|
|
2077
|
+
innerMessage.innerHTML = err.error && err.error.message ? err.error.message : err.message;
|
|
2078
|
+
}
|
|
2079
|
+
this.dataTable.context[0].oLanguage.sEmptyTable =
|
|
2080
|
+
this.dataTable.context[0].oLanguage.sZeroRecords = this.errorTemplate.nativeElement.innerHTML;
|
|
2081
|
+
}
|
|
2082
|
+
else {
|
|
2083
|
+
if (innerMessage) {
|
|
2084
|
+
innerMessage.innerHTML = '';
|
|
2085
|
+
}
|
|
2086
|
+
this.dataTable.context[0].oLanguage.sEmptyTable = this.dataTable.context[0].oLanguage.sZeroRecords = '';
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
1780
2090
|
clearEmptyTable() {
|
|
1781
2091
|
if (this.dataTable && this.dataTable.context[0]) {
|
|
1782
|
-
this.dataTable.context[0].oLanguage.sEmptyTable = '';
|
|
2092
|
+
this.dataTable.context[0].oLanguage.sEmptyTable = this.dataTable.context[0].oLanguage.sZeroRecords = '';
|
|
1783
2093
|
}
|
|
1784
2094
|
}
|
|
1785
2095
|
export() {
|
|
@@ -1892,6 +2202,125 @@ class AdvancedTableComponent {
|
|
|
1892
2202
|
}
|
|
1893
2203
|
});
|
|
1894
2204
|
}
|
|
2205
|
+
/**
|
|
2206
|
+
*
|
|
2207
|
+
* @param options to pass an errorHandler callback, if desired
|
|
2208
|
+
* @returns void
|
|
2209
|
+
*/
|
|
2210
|
+
exportView(options) {
|
|
2211
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2212
|
+
try {
|
|
2213
|
+
this._loading.showLoading();
|
|
2214
|
+
// validate query items and config
|
|
2215
|
+
if (!(this._lastQueryTotalItems && this.config)) {
|
|
2216
|
+
// do nothing
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
// get export settings
|
|
2220
|
+
const exportSettings = this._configuration.settings;
|
|
2221
|
+
// and export limit
|
|
2222
|
+
const exportLimit = (exportSettings && exportSettings.tables && exportSettings.tables.exportLimit > 0)
|
|
2223
|
+
? exportSettings.tables.exportLimit : MAX_EXPORT_ITEMS;
|
|
2224
|
+
// and validate it
|
|
2225
|
+
if (this._lastQueryTotalItems > exportLimit) {
|
|
2226
|
+
// call error handler
|
|
2227
|
+
// provide a recognizible error type
|
|
2228
|
+
if (options && options.errorHandler) {
|
|
2229
|
+
options.errorHandler(new ExportLimitExceededError('Export limit exceeded'));
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
// or show warning modal and exit
|
|
2233
|
+
this._modalService.showWarningDialog(this._translateService.instant('Tables.ExportList'), this._translateService.instant('Tables.ExportLimitExceeded', { dataLength: this._lastQueryTotalItems, exportLimit }), DIALOG_BUTTONS.Ok);
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
// get total displayed items
|
|
2237
|
+
const totalDisplayedItems = Array.from(this.dataTable.context[0].aiDisplay).length;
|
|
2238
|
+
// if they already satisfy the last query total
|
|
2239
|
+
if (totalDisplayedItems === this._lastQueryTotalItems) {
|
|
2240
|
+
// prepare excel data immediately
|
|
2241
|
+
const { body, header } = this.getExportableData();
|
|
2242
|
+
// and export them to excel
|
|
2243
|
+
this._exportSpreadsheet.export(body, `${this._translateService.instant(this.config.title || 'Tables.ExportResults')}.xlsx`, {
|
|
2244
|
+
header,
|
|
2245
|
+
skipHeader: false
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
else {
|
|
2249
|
+
// at this point, more data need to be fetched
|
|
2250
|
+
// hold previous data state
|
|
2251
|
+
const previousDataState = this.dataTable.rows().data().toArray();
|
|
2252
|
+
// get target data state by executing the last query
|
|
2253
|
+
// note: taking the exportLimit amount of items will always satisfy the results,
|
|
2254
|
+
// because it has been validated
|
|
2255
|
+
const targetDataState = yield this.lastQuery.take(exportLimit).getItems();
|
|
2256
|
+
// change table data on the fly, but do not redraw
|
|
2257
|
+
this.dataTable.clear().rows.add(targetDataState);
|
|
2258
|
+
// prepare excel data
|
|
2259
|
+
const { body, header } = this.getExportableData();
|
|
2260
|
+
// reset table data
|
|
2261
|
+
this.dataTable.clear().rows.add(previousDataState);
|
|
2262
|
+
// and export target data to excel
|
|
2263
|
+
this._exportSpreadsheet.export(body, `${this._translateService.instant(this.config.title || 'Tables.ExportResults')}.xlsx`, {
|
|
2264
|
+
header,
|
|
2265
|
+
skipHeader: false
|
|
2266
|
+
});
|
|
2267
|
+
}
|
|
2268
|
+
// exit
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
catch (err) {
|
|
2272
|
+
// log error
|
|
2273
|
+
console.error(err);
|
|
2274
|
+
// call error handler, if defined
|
|
2275
|
+
if (options && options.errorHandler) {
|
|
2276
|
+
options.errorHandler(err);
|
|
2277
|
+
}
|
|
2278
|
+
else {
|
|
2279
|
+
// use default error service
|
|
2280
|
+
this._errorService.showError(err, {
|
|
2281
|
+
continueLink: '.'
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
finally {
|
|
2286
|
+
this._loading.hideLoading();
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
getExportableData() {
|
|
2291
|
+
if (!(this.dataTable && this.dataTable.buttons
|
|
2292
|
+
&& typeof this.dataTable.buttons.exportData === 'function' && this.config)) {
|
|
2293
|
+
return { body: [], header: [] };
|
|
2294
|
+
}
|
|
2295
|
+
// fetch exportable excel data
|
|
2296
|
+
let { body, header } = this.dataTable.buttons.exportData();
|
|
2297
|
+
const cleanupIndexes = [];
|
|
2298
|
+
// clean up headers
|
|
2299
|
+
header = header.filter((headerItem, index) => {
|
|
2300
|
+
// exclude empty headers
|
|
2301
|
+
if (headerItem.trim().length === 0) {
|
|
2302
|
+
cleanupIndexes.push(index);
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2305
|
+
// find item by title
|
|
2306
|
+
const findItem = this.config.columns.find((column) => {
|
|
2307
|
+
return column.title && column.title.length && this._translateService.instant(column.title) === headerItem;
|
|
2308
|
+
});
|
|
2309
|
+
// exclude hidden columns
|
|
2310
|
+
if (findItem && findItem.hidden === true) {
|
|
2311
|
+
cleanupIndexes.push(index);
|
|
2312
|
+
return false;
|
|
2313
|
+
}
|
|
2314
|
+
return true;
|
|
2315
|
+
});
|
|
2316
|
+
// clean up body
|
|
2317
|
+
body = body.map((row) => {
|
|
2318
|
+
return row.filter((_, rowIndex) => {
|
|
2319
|
+
return cleanupIndexes.indexOf(rowIndex) === -1;
|
|
2320
|
+
});
|
|
2321
|
+
});
|
|
2322
|
+
return { body, header };
|
|
2323
|
+
}
|
|
1895
2324
|
}
|
|
1896
2325
|
AdvancedTableComponent.decorators = [
|
|
1897
2326
|
{ type: Component, args: [{
|
|
@@ -1903,17 +2332,31 @@ AdvancedTableComponent.decorators = [
|
|
|
1903
2332
|
<div #emptyTable class="d-none">
|
|
1904
2333
|
<div>
|
|
1905
2334
|
<div class="mt-4">
|
|
1906
|
-
<div class="icon-circle bg-gray-300 border-gray-100"></div>
|
|
2335
|
+
<div class="icon-circle bg-gray-300 border-gray-100"></div>
|
|
2336
|
+
</div>
|
|
2337
|
+
<div class="mt-4">
|
|
2338
|
+
<h4 class="font-3xl text-dark" [translate]="'Tables.EmptyTableTitle'"></h4>
|
|
2339
|
+
<p class="font-lg text-dark" [translate]="'Tables.EmptyTableMessage'"></p>
|
|
2340
|
+
</div>
|
|
2341
|
+
</div>
|
|
2342
|
+
</div>
|
|
2343
|
+
<div #errorTemplate class="d-none error-message">
|
|
2344
|
+
<div class="text-center">
|
|
2345
|
+
<div class="mt-4">
|
|
2346
|
+
<div class="icon-circle bg-danger border-gray-100"></div>
|
|
1907
2347
|
</div>
|
|
1908
2348
|
<div class="mt-4">
|
|
1909
|
-
<h4 class="font-3xl text-
|
|
1910
|
-
<p class="font-lg text-
|
|
2349
|
+
<h4 class="font-3xl text-secondary" [translate]="'Tables.DataError.Title'"></h4>
|
|
2350
|
+
<p class="font-lg text-secondary mb-1" [translate]="'Tables.DataError.Message'"></p>
|
|
2351
|
+
<p class="font-lg text-secondary error-inner-message">
|
|
2352
|
+
<small></small>
|
|
2353
|
+
</p>
|
|
1911
2354
|
</div>
|
|
1912
2355
|
</div>
|
|
1913
2356
|
</div>
|
|
1914
2357
|
`,
|
|
1915
2358
|
encapsulation: ViewEncapsulation.None,
|
|
1916
|
-
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}"]
|
|
2359
|
+
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 .error-inner-message>small{overflow-wrap:break-word}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}"]
|
|
1917
2360
|
}] }
|
|
1918
2361
|
];
|
|
1919
2362
|
/** @nocollapse */
|
|
@@ -1928,11 +2371,16 @@ AdvancedTableComponent.ctorParameters = () => [
|
|
|
1928
2371
|
{ type: TemplatePipe },
|
|
1929
2372
|
{ type: LoadingService },
|
|
1930
2373
|
{ type: HttpClient },
|
|
1931
|
-
{ type: ColumnSelectorService }
|
|
2374
|
+
{ type: ColumnSelectorService },
|
|
2375
|
+
{ type: ConfigurationService },
|
|
2376
|
+
{ type: ExportSpreadsheetService },
|
|
2377
|
+
{ type: ModalService },
|
|
2378
|
+
{ type: ErrorService }
|
|
1932
2379
|
];
|
|
1933
2380
|
AdvancedTableComponent.propDecorators = {
|
|
1934
2381
|
table: [{ type: ViewChild, args: ['table',] }],
|
|
1935
2382
|
emptyTable: [{ type: ViewChild, args: ['emptyTable',] }],
|
|
2383
|
+
errorTemplate: [{ type: ViewChild, args: ['errorTemplate',] }],
|
|
1936
2384
|
loadingTable: [{ type: ViewChild, args: ['loadingTable',] }],
|
|
1937
2385
|
height: [{ type: Input }],
|
|
1938
2386
|
showActions: [{ type: Input }],
|
|
@@ -2981,37 +3429,6 @@ AdvancedSearchConfigurationResolver.ctorParameters = () => [
|
|
|
2981
3429
|
{ type: HttpClient }
|
|
2982
3430
|
];
|
|
2983
3431
|
|
|
2984
|
-
class ActivatedTableService {
|
|
2985
|
-
constructor(_router, _activatedRoute) {
|
|
2986
|
-
this._router = _router;
|
|
2987
|
-
this._activatedRoute = _activatedRoute;
|
|
2988
|
-
_router.events.forEach((event) => {
|
|
2989
|
-
if (event instanceof NavigationStart) {
|
|
2990
|
-
if (this._activeTable) {
|
|
2991
|
-
this._activeTable = null;
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
});
|
|
2995
|
-
}
|
|
2996
|
-
get activeTable() {
|
|
2997
|
-
return this._activeTable;
|
|
2998
|
-
}
|
|
2999
|
-
set activeTable(tableComponent) {
|
|
3000
|
-
this._activeTable = tableComponent;
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
ActivatedTableService.decorators = [
|
|
3004
|
-
{ type: Injectable, args: [{
|
|
3005
|
-
providedIn: 'root'
|
|
3006
|
-
},] }
|
|
3007
|
-
];
|
|
3008
|
-
/** @nocollapse */
|
|
3009
|
-
ActivatedTableService.ctorParameters = () => [
|
|
3010
|
-
{ type: Router },
|
|
3011
|
-
{ type: ActivatedRoute }
|
|
3012
|
-
];
|
|
3013
|
-
ActivatedTableService.ngInjectableDef = defineInjectable({ factory: function ActivatedTableService_Factory() { return new ActivatedTableService(inject(Router), inject(ActivatedRoute)); }, token: ActivatedTableService, providedIn: "root" });
|
|
3014
|
-
|
|
3015
3432
|
class AdvancedTableSettingsComponent {
|
|
3016
3433
|
constructor(_context, _activatedRoute, elRef, modalService, userStorage, formBuilder, _activatedTable) {
|
|
3017
3434
|
this._context = _context;
|
|
@@ -3841,226 +4258,6 @@ AdvancedTableEditorDirective.propDecorators = {
|
|
|
3841
4258
|
dirtyChange: [{ type: Output }]
|
|
3842
4259
|
};
|
|
3843
4260
|
|
|
3844
|
-
const MAX_EXPORT_ITEMS = 500;
|
|
3845
|
-
class BtnExpDirective {
|
|
3846
|
-
constructor(_activatedTable, _context, _config, _translate, _loadingService, _errorService) {
|
|
3847
|
-
this._activatedTable = _activatedTable;
|
|
3848
|
-
this._context = _context;
|
|
3849
|
-
this._config = _config;
|
|
3850
|
-
this._translate = _translate;
|
|
3851
|
-
this._loadingService = _loadingService;
|
|
3852
|
-
this._errorService = _errorService;
|
|
3853
|
-
}
|
|
3854
|
-
clickEvent(event) {
|
|
3855
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3856
|
-
event.preventDefault();
|
|
3857
|
-
event.stopPropagation();
|
|
3858
|
-
if (this._activatedTable.activeTable) {
|
|
3859
|
-
const lastQuery = this._activatedTable.activeTable.lastQuery;
|
|
3860
|
-
const tableConfig = this._activatedTable.activeTable.config;
|
|
3861
|
-
const serviceHeaders = this._context.getService().getHeaders();
|
|
3862
|
-
const queryModel = lastQuery.getModel();
|
|
3863
|
-
let query = this._context.model(queryModel).asQueryable();
|
|
3864
|
-
const queryParams = lastQuery.getParams();
|
|
3865
|
-
query = this.constructQuery(query, queryParams, tableConfig, serviceHeaders);
|
|
3866
|
-
// get export settings
|
|
3867
|
-
const exportSettings = this._config.settings;
|
|
3868
|
-
// get export limit
|
|
3869
|
-
const maxExportItems = exportSettings && exportSettings.tables && exportSettings.tables.exportLimit;
|
|
3870
|
-
if (maxExportItems && typeof maxExportItems === 'number' && maxExportItems > 0) {
|
|
3871
|
-
query.skip(0).take(maxExportItems);
|
|
3872
|
-
}
|
|
3873
|
-
else {
|
|
3874
|
-
query.skip(0).take(MAX_EXPORT_ITEMS);
|
|
3875
|
-
}
|
|
3876
|
-
// This constructs the URI based on the way @themost does
|
|
3877
|
-
const url = this.constructURL(query);
|
|
3878
|
-
this.downloadFile(url, query.getService().getHeaders(), query.getModel());
|
|
3879
|
-
}
|
|
3880
|
-
});
|
|
3881
|
-
}
|
|
3882
|
-
/**
|
|
3883
|
-
* Sets the parameters to the query based on
|
|
3884
|
-
* the active filters of the activated table
|
|
3885
|
-
* @param {ClientDataQueryable} query
|
|
3886
|
-
* @param params: The filters of the last query of the activated table
|
|
3887
|
-
* @return ClientDataQueryable
|
|
3888
|
-
*/
|
|
3889
|
-
setParams(query, params) {
|
|
3890
|
-
if (params && typeof params === 'object') {
|
|
3891
|
-
Object.keys(params).forEach((key) => {
|
|
3892
|
-
query.setParam(key, params[key]);
|
|
3893
|
-
});
|
|
3894
|
-
}
|
|
3895
|
-
return query;
|
|
3896
|
-
}
|
|
3897
|
-
/**
|
|
3898
|
-
* Sets the headers to the query based on
|
|
3899
|
-
* the default headers of the DataContext
|
|
3900
|
-
* and appending the accept header to get
|
|
3901
|
-
* an xlsx file from the API
|
|
3902
|
-
* @param {ClientDataQueryable} query
|
|
3903
|
-
* @param {Headers} headers: The headers to append to the query
|
|
3904
|
-
* @return ClientDataQueryable
|
|
3905
|
-
*/
|
|
3906
|
-
setHeaders(query, headers) {
|
|
3907
|
-
Object.keys(headers).forEach((key) => {
|
|
3908
|
-
if (headers.hasOwnProperty(key)) {
|
|
3909
|
-
query.getService().setHeader(key, headers[key]);
|
|
3910
|
-
}
|
|
3911
|
-
});
|
|
3912
|
-
// sets a header to accept xlsx files
|
|
3913
|
-
query.getService().setHeader('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
3914
|
-
return query;
|
|
3915
|
-
}
|
|
3916
|
-
/**
|
|
3917
|
-
* Constructs the select parameter of the
|
|
3918
|
-
* ClientDataQuery by replacing the target name
|
|
3919
|
-
* of the field based on the localized translation
|
|
3920
|
-
* of that property on the advanced tabled
|
|
3921
|
-
* @param {ClientDataQueryable} query
|
|
3922
|
-
* @param tableConfig: The configuration of the activated table
|
|
3923
|
-
* @return ClientDataQueryable
|
|
3924
|
-
*/
|
|
3925
|
-
constructQueryParam(query, tableConfig) {
|
|
3926
|
-
let selectQuery = query.getParams().$select;
|
|
3927
|
-
let selectQueryArray = selectQuery.split(',');
|
|
3928
|
-
selectQueryArray = selectQueryArray.map((select$$1) => {
|
|
3929
|
-
const words = select$$1.split(' ');
|
|
3930
|
-
if (words.length === 3) {
|
|
3931
|
-
if (tableConfig && tableConfig.columns) {
|
|
3932
|
-
for (const column of tableConfig.columns) {
|
|
3933
|
-
if (column.property === words[2] && column.title) {
|
|
3934
|
-
words[2] = `"${this._translate.instant(column.title)}"`;
|
|
3935
|
-
}
|
|
3936
|
-
else if (column.property === words[2]) {
|
|
3937
|
-
words[2] = `"${this._translate.instant(words[2])}"`;
|
|
3938
|
-
}
|
|
3939
|
-
}
|
|
3940
|
-
}
|
|
3941
|
-
}
|
|
3942
|
-
if (words.length === 1) {
|
|
3943
|
-
if (tableConfig && tableConfig.columns) {
|
|
3944
|
-
for (const column of tableConfig.columns) {
|
|
3945
|
-
if (column.name === words[0] && column.title) {
|
|
3946
|
-
words[0] = `${words[0]} as "${this._translate.instant(column.title)}"`;
|
|
3947
|
-
break;
|
|
3948
|
-
}
|
|
3949
|
-
else if (column.name === words[0] && column.property) {
|
|
3950
|
-
words[0] = `${words[0]} as "${this._translate.instant(column.property)}"`;
|
|
3951
|
-
break;
|
|
3952
|
-
}
|
|
3953
|
-
else if (words[0] === column.name && words[0] === "id" && column.hidden) {
|
|
3954
|
-
break;
|
|
3955
|
-
}
|
|
3956
|
-
else if (words[0] == column.name || words[0] === column.property) {
|
|
3957
|
-
words[0] = `${words[0]} as "${this._translate.instant(words[0])}"`;
|
|
3958
|
-
}
|
|
3959
|
-
}
|
|
3960
|
-
}
|
|
3961
|
-
return words[0];
|
|
3962
|
-
}
|
|
3963
|
-
return words.join(' ');
|
|
3964
|
-
});
|
|
3965
|
-
selectQuery = selectQueryArray.join(',');
|
|
3966
|
-
query.setParam('$select', selectQuery);
|
|
3967
|
-
return query;
|
|
3968
|
-
}
|
|
3969
|
-
/**
|
|
3970
|
-
* Constructs the fetch URL based the query parameters
|
|
3971
|
-
* @param {ClientDataQueryable} query
|
|
3972
|
-
* @return String
|
|
3973
|
-
*/
|
|
3974
|
-
constructURL(query) {
|
|
3975
|
-
const baseURL = query.getService().getBase();
|
|
3976
|
-
let url = baseURL.endsWith('/') ? (baseURL + query.getModel() + '?') : (baseURL + '/' + query.getModel() + '?');
|
|
3977
|
-
Object.keys(query.getParams()).forEach((key, index) => {
|
|
3978
|
-
if (index === 0) {
|
|
3979
|
-
url += key + '=' + query.getParams()[key];
|
|
3980
|
-
}
|
|
3981
|
-
else {
|
|
3982
|
-
url += '&' + key + '=' + query.getParams()[key];
|
|
3983
|
-
}
|
|
3984
|
-
});
|
|
3985
|
-
return url;
|
|
3986
|
-
}
|
|
3987
|
-
/**
|
|
3988
|
-
* Constructs the query by setting the parameters of the
|
|
3989
|
-
* advanced table's active filters, sets the necessary headers
|
|
3990
|
-
* and build the select parameter of the query
|
|
3991
|
-
* @param {ClientDataQueryable} query
|
|
3992
|
-
* @param params: The filters of the last query of the activated table
|
|
3993
|
-
* @param tableConfig: The configuration of the activated table
|
|
3994
|
-
* @param {Headers} headers: The headers to append to the query
|
|
3995
|
-
* @return ClientDataQueryable
|
|
3996
|
-
*/
|
|
3997
|
-
constructQuery(query, params, tableConfig, headers) {
|
|
3998
|
-
let _query = this.setParams(query, params);
|
|
3999
|
-
_query = this.setHeaders(_query, headers);
|
|
4000
|
-
_query = this.constructQueryParam(_query, tableConfig);
|
|
4001
|
-
return _query;
|
|
4002
|
-
}
|
|
4003
|
-
/**
|
|
4004
|
-
* Fetches and saves the xlsx file
|
|
4005
|
-
* @param {String} url
|
|
4006
|
-
* @param {Headers} serviceHeaders: The headers to append to the query
|
|
4007
|
-
* @param modelName: The model name of the advanced table
|
|
4008
|
-
*/
|
|
4009
|
-
downloadFile(url, serviceHeaders, modelName) {
|
|
4010
|
-
this._loadingService.showLoading();
|
|
4011
|
-
fetch(encodeURI(url), {
|
|
4012
|
-
headers: serviceHeaders,
|
|
4013
|
-
credentials: 'include'
|
|
4014
|
-
}).then(response => {
|
|
4015
|
-
if (response && !response.ok) {
|
|
4016
|
-
throw new ResponseError(response.statusText, response.status);
|
|
4017
|
-
}
|
|
4018
|
-
return response.blob();
|
|
4019
|
-
}).then(blob => {
|
|
4020
|
-
const objectUrl = window.URL.createObjectURL(blob);
|
|
4021
|
-
const a = document.createElement('a');
|
|
4022
|
-
document.body.appendChild(a);
|
|
4023
|
-
a.setAttribute('style', 'display: none');
|
|
4024
|
-
a.href = objectUrl;
|
|
4025
|
-
const downloadName = `${modelName}.xlsx`;
|
|
4026
|
-
a.download = downloadName;
|
|
4027
|
-
// this adds support for IE and MS Edge (up to version 44.19041)
|
|
4028
|
-
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
|
4029
|
-
window.navigator.msSaveOrOpenBlob(blob, downloadName);
|
|
4030
|
-
}
|
|
4031
|
-
else {
|
|
4032
|
-
// for all other browsers
|
|
4033
|
-
a.click();
|
|
4034
|
-
}
|
|
4035
|
-
window.URL.revokeObjectURL(objectUrl);
|
|
4036
|
-
a.remove();
|
|
4037
|
-
this._loadingService.hideLoading();
|
|
4038
|
-
}).catch(err => {
|
|
4039
|
-
this._loadingService.hideLoading();
|
|
4040
|
-
this._errorService.showError(err, {
|
|
4041
|
-
continueLink: '.'
|
|
4042
|
-
});
|
|
4043
|
-
});
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
BtnExpDirective.decorators = [
|
|
4047
|
-
{ type: Directive, args: [{
|
|
4048
|
-
selector: '.universis-btn-export'
|
|
4049
|
-
},] }
|
|
4050
|
-
];
|
|
4051
|
-
/** @nocollapse */
|
|
4052
|
-
BtnExpDirective.ctorParameters = () => [
|
|
4053
|
-
{ type: ActivatedTableService },
|
|
4054
|
-
{ type: AngularDataContext },
|
|
4055
|
-
{ type: ConfigurationService },
|
|
4056
|
-
{ type: TranslateService },
|
|
4057
|
-
{ type: LoadingService },
|
|
4058
|
-
{ type: ErrorService }
|
|
4059
|
-
];
|
|
4060
|
-
BtnExpDirective.propDecorators = {
|
|
4061
|
-
clickEvent: [{ type: HostListener, args: ['click', ['$event'],] }]
|
|
4062
|
-
};
|
|
4063
|
-
|
|
4064
4261
|
class AdvancedAggregatorService {
|
|
4065
4262
|
constructor(_context, _template) {
|
|
4066
4263
|
this._context = _context;
|
|
@@ -4546,6 +4743,8 @@ ParseTitlePipe.ctorParameters = () => [
|
|
|
4546
4743
|
{ type: TranslateService }
|
|
4547
4744
|
];
|
|
4548
4745
|
|
|
4746
|
+
// tslint:disable: quotemark
|
|
4747
|
+
// tslint:disable: max-line-length
|
|
4549
4748
|
const TABLES_EL = {
|
|
4550
4749
|
"Tables": {
|
|
4551
4750
|
"Export": "Εξαγωγή",
|
|
@@ -4625,7 +4824,14 @@ const TABLES_EL = {
|
|
|
4625
4824
|
"MoveColumnHelp": "Χρησιμοποιήστε τα πλήκτρα 'Επάνω' και 'Κάτω' για να αλλάξετε την σειρά εμφάνισης των στηλών του πίνακα.",
|
|
4626
4825
|
"UnknownColumn": "Άγνωστο",
|
|
4627
4826
|
"SelectColumn": "Επιλογή",
|
|
4628
|
-
"ActionLinkColumn": "Ενέργειες"
|
|
4827
|
+
"ActionLinkColumn": "Ενέργειες",
|
|
4828
|
+
"DataError": {
|
|
4829
|
+
"Title": "Σφάλμα κατά την παραλαβή των δεδομένων",
|
|
4830
|
+
"Message": "Συνέβη σφάλμα κατά την παραλαβή των δεδομένων. Προσπαθήστε ξανά ή τροποποιήστε τα στοιχεία αναζήτησης."
|
|
4831
|
+
},
|
|
4832
|
+
"ExportList": "Εξαγωγή λίστας",
|
|
4833
|
+
"ExportLimitExceeded": "Το πλήθος των στοιχείων προς εξαγωγή ({{dataLength}}) ξεπερνάει το μέγιστο επιτρεπτό ({{exportLimit}}). Παρακαλούμε προσαρμόστε τα φίλτρα της αναζήτησης και προσπαθήστε ξανά.",
|
|
4834
|
+
"ExportResults": "Δεδομένα λίστας"
|
|
4629
4835
|
},
|
|
4630
4836
|
"TrueFalse": {
|
|
4631
4837
|
"long": {
|
|
@@ -4666,6 +4872,8 @@ const TABLES_EL = {
|
|
|
4666
4872
|
}
|
|
4667
4873
|
};
|
|
4668
4874
|
|
|
4875
|
+
// tslint:disable: quotemark
|
|
4876
|
+
// tslint:disable: max-line-length
|
|
4669
4877
|
const TABLES_EN = {
|
|
4670
4878
|
"Tables": {
|
|
4671
4879
|
"Export": "Export",
|
|
@@ -4744,7 +4952,14 @@ const TABLES_EN = {
|
|
|
4744
4952
|
"MoveColumnHelp": "Use 'Move up' and 'Move down' buttons to change column order.",
|
|
4745
4953
|
"UnknownColumn": "Unknown",
|
|
4746
4954
|
"SelectColumn": "Select",
|
|
4747
|
-
"ActionLinkColumn": "Actions"
|
|
4955
|
+
"ActionLinkColumn": "Actions",
|
|
4956
|
+
"DataError": {
|
|
4957
|
+
"Title": "Error while getting data",
|
|
4958
|
+
"Message": "An error occurred while getting data. Please try again or change your criteria."
|
|
4959
|
+
},
|
|
4960
|
+
"ExportList": "Export list",
|
|
4961
|
+
"ExportLimitExceeded": "The number of items that are to be exported ({{dataLength}}) exceeds the export limit ({{exportLimit}}). Please apply more specific filters to the search.",
|
|
4962
|
+
"ExportResults": "Exported list"
|
|
4748
4963
|
},
|
|
4749
4964
|
"TrueFalse": {
|
|
4750
4965
|
"long": {
|
|
@@ -5042,7 +5257,7 @@ AdvancedSearchRouterState.ctorParameters = () => [
|
|
|
5042
5257
|
{ type: Router }
|
|
5043
5258
|
];
|
|
5044
5259
|
|
|
5045
|
-
const ɵ0 = FORMATTERS;
|
|
5260
|
+
const ɵ0$1 = FORMATTERS;
|
|
5046
5261
|
class TablesModule {
|
|
5047
5262
|
constructor(_translateService) {
|
|
5048
5263
|
this._translateService = _translateService;
|
|
@@ -5078,7 +5293,7 @@ TablesModule.decorators = [
|
|
|
5078
5293
|
providers: [DatePipe, TemplatePipe,
|
|
5079
5294
|
{
|
|
5080
5295
|
provide: COLUMN_FORMATTERS,
|
|
5081
|
-
useValue: ɵ0
|
|
5296
|
+
useValue: ɵ0$1
|
|
5082
5297
|
},
|
|
5083
5298
|
AdvancedTableConfigurationResolver,
|
|
5084
5299
|
AdvancedSearchConfigurationResolver,
|
|
@@ -5155,6 +5370,6 @@ TablesModule.ctorParameters = () => [
|
|
|
5155
5370
|
* Generated bundle index. Do not edit.
|
|
5156
5371
|
*/
|
|
5157
5372
|
|
|
5158
|
-
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, AdvancedTableSettingsComponent, AdvancedTableSearchBaseComponent, AdvancedTableSearchComponent, FORMATTERS, AdvancedFilterValueProvider, AdvancedTableModalBaseTemplate, AdvancedTableModalBaseComponent, SimpleHeaderToolsComponent, TableSimpleHeaderComponent, AdvancedTableNotNullError, AdvancedTableEditorDirective, BtnExpDirective, AdvancedAggregatorComponent, AdvancedAggregatorListComponent, AddItemsComponent, AdvancedAggregatorPipe, ParseTitlePipe, AdvancedAggregatorService, TablesModule,
|
|
5373
|
+
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 };
|
|
5159
5374
|
|
|
5160
5375
|
//# sourceMappingURL=universis-ngx-tables.js.map
|