stimulsoft-designer-angular
Version:
The Angular Designer component is developed to create reports and dashboards in web browser.
485 lines (477 loc) • 21.1 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Component, ViewChild, Output, Input, NgModule } from '@angular/core';
import { catchError, EMPTY } from 'rxjs';
import * as i1 from '@angular/common/http';
import { CommonModule } from '@angular/common';
class FileSaverService {
constructor() {
this._global = typeof window === 'object' && window.window === window
? window : typeof self === 'object' && self.self === self
? self : /*typeof global === 'object' && global.global === global
? global
: */
this;
// Detect WebView inside a native macOS app by ruling out all browsers
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
this.isMacOSWebView = this._global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);
this.saveAs = this._global.saveAs || (
// probably in some web worker
(typeof window !== 'object' || window !== this._global)
? function saveAs() { }
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
: ('download' in HTMLAnchorElement.prototype && !this.isMacOSWebView)
? function saveAs(blob, name, opts) {
let URL = this._global.URL || this._global.webkitURL;
let a = document.createElement('a');
name = name || blob.name || 'download';
a.download = name;
a.rel = 'noopener'; // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === 'string') {
// Support regular links
a.href = blob;
if (a.origin !== location.origin) {
this.corsEnabled(a.href)
? this.download(blob, name, opts)
: this.click(a, a.target = '_blank');
}
else {
this.click(a);
}
}
else {
// Support blobs
a.href = URL.createObjectURL(blob);
let this_ = this;
setTimeout(function () { URL.revokeObjectURL(a.href); }, 4E4); // 40s
setTimeout(function () { this_.click(a); }, 0);
}
}
// Use msSaveOrOpenBlob as a second approach
: 'msSaveOrOpenBlob' in navigator
? function saveAs(blob, name, opts) {
name = name || blob.name || 'download';
if (typeof blob === 'string') {
if (this.corsEnabled(blob)) {
this.download(blob, name, opts);
}
else {
let a = document.createElement('a');
a.href = blob;
a.target = '_blank';
let this_ = this;
setTimeout(function () { this_.click(a); });
}
}
else {
navigator.msSaveOrOpenBlob(this.bom(blob, opts), name);
}
}
// Fallback to using FileReader and a popup
: function saveAs(blob, name, opts, popup) {
// Open a popup immediately do go around popup blocker
// Mostly only available on user interaction and the fileReader is async so...
popup = popup || open('', '_blank');
if (popup) {
popup.document.title =
popup.document.body.innerText = 'downloading...';
}
if (typeof blob === 'string')
return this.download(blob, name, opts);
let force = blob.type === 'application/octet-stream';
let isSafari = /constructor/i.test(this._global.HTMLElement) || this._global.safari;
let isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((isChromeIOS || (force && isSafari) || this.isMacOSWebView) && typeof FileReader !== 'undefined') {
// Safari doesn't allow downloading of blob URLs
let reader = new FileReader();
reader.onloadend = function () {
let url = reader.result;
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
if (popup)
popup.location.href = url;
else
location = url;
popup = null; // reverse-tabnabbing #460
};
reader.readAsDataURL(blob);
}
else {
let URL = this._global.URL || this._global.webkitURL;
let url = URL.createObjectURL(blob);
if (popup)
popup.location = url;
else
location.href = url;
popup = null; // reverse-tabnabbing #460
setTimeout(function () { URL.revokeObjectURL(url); }, 4E4); // 40s
}
});
this._global.saveAs = this.saveAs.saveAs = this.saveAs;
/*if (typeof module !== 'undefined') {
module.exports = this.saveAs;
}*/
}
bom(blob, opts) {
if (typeof opts === 'undefined')
opts = { autoBom: false };
else if (typeof opts !== 'object') {
console.warn('Deprecated: Expected third argument to be a object');
opts = { autoBom: !opts };
}
// prepend BOM for UTF-8 XML and text/* types (including HTML)
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type });
}
return blob;
}
download(url, name, opts) {
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
let this_ = this;
xhr.onload = function () {
this_.saveAs(xhr.response, name, opts);
};
xhr.onerror = function () {
console.error('could not download file');
};
xhr.send();
}
corsEnabled(url) {
let xhr = new XMLHttpRequest();
// use sync to avoid popup blocker
xhr.open('HEAD', url, false);
try {
xhr.send();
}
catch (e) { }
return xhr.status >= 200 && xhr.status <= 299;
}
// `a.click()` doesn't work for all browsers (#465)
click(node) {
try {
node.dispatchEvent(new MouseEvent('click'));
}
catch (e) {
let evt = document.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
node.dispatchEvent(evt);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSaverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSaverService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileSaverService, decorators: [{
type: Injectable
}], ctorParameters: () => [] });
class ProxyService {
constructor(httpClient, fileSaver) {
this.httpClient = httpClient;
this.fileSaver = fileSaver;
this.openReport = false;
}
createConnection() {
let request = new Object();
request.method = "POST";
request.url = "";
request.headers = {};
request.responseType = "text";
request.readyState = 1;
request.status = 0;
request.responseText = null;
request.statusText = null;
request.id = null;
request.open = (method, url) => {
request.method = method;
request.url = url;
};
request.setRequestHeader = (key, value) => {
request.headers[key] = value;
};
request.abort = () => {
};
request.onreadystatechange = () => { };
request.send = (data) => {
let formData;
if (typeof data == 'object') {
formData = new FormData();
Object.keys(data).forEach(key => formData.append(key, data[key]));
}
let needGet = data && data["stiweb_action"] === "Resource";
let observable;
if (needGet) {
observable = this.httpClient.get(request.url, formData ?? data).pipe(catchError((error) => {
return this.catchError(error, request);
}));
}
else {
observable = this.httpClient.post(request.url, formData ?? data, { responseType: request.responseType }).pipe(catchError((error) => {
return this.catchError(error, request);
}));
}
let downloadFileName;
try {
let dataObj = JSON.parse(window["StiBase64"].decode(data.stiweb_parameters));
downloadFileName = dataObj.command == "DownloadReport" ? dataObj.reportFile : null;
}
catch { }
observable.subscribe(data => {
request.readyState = 4;
let resultData = needGet ? JSON.stringify(data) : data;
if (request.responseType == "text")
request.responseText = resultData;
else
request.response = resultData;
request.status = 200;
if (downloadFileName) {
let blob = new Blob([data], { type: "application/xml", });
this.fileSaver.saveAs(blob, downloadFileName);
request.responseText = "{\"command\":\"SaveReport\"}";
}
request.onreadystatechange();
});
};
return request;
}
;
catchError(error, request) {
alert(JSON.stringify(error));
request.status = error.status;
request.statusText = error.statusText;
request.responseText = error.error;
request.readyState = 4;
request.onreadystatechange();
return EMPTY;
}
error(message) {
}
export(data) {
}
email(data) {
}
print(data) {
}
design() {
}
postParametersFunction(data) {
return this.postParametersFunction_ ? this.postParametersFunction_(data) : {};
}
getFormData(data) {
const formData = new FormData();
Object.keys(data).forEach(key => formData.append(key, data[key]));
return formData;
}
getData2(url, data) {
return this.httpClient.post(url, this.getFormData(data), { responseType: 'blob' }).pipe(catchError((error) => {
console.error(error);
return EMPTY;
}));
}
saveData(url, params, newWindow, retrieveFileName) {
if (retrieveFileName) {
params.stiweb_onlyFileName = true;
debugger;
let observable = this.httpClient.post(url, this.getFormData(params), { responseType: 'json' }).pipe(catchError((error) => {
console.error(error);
return EMPTY;
}));
observable.subscribe(resp => {
let fileName = resp.fileName;
delete params.stiweb_onlyFileName;
this.getData2(url, params).subscribe((data) => {
this.showData(data, fileName, newWindow);
});
});
}
else {
this.getData2(url, params).subscribe((data) => {
this.showData(data, null, newWindow);
});
}
}
showData(data, fileName, newWindow) {
if (newWindow) {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(data);
}
else {
var fileURL = URL.createObjectURL(data);
window.open(fileURL, '_blank');
}
}
else {
this.fileSaver.saveAs(data, fileName);
}
}
async getText(url) {
return new Promise((resolve, reject) => {
let observable = this.httpClient.get(url, { responseType: 'text' }).pipe(catchError((error) => {
console.log(error);
return EMPTY;
}));
observable.subscribe(data => {
resolve(data);
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProxyService, deps: [{ token: i1.HttpClient }, { token: FileSaverService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProxyService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProxyService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: FileSaverService }] });
class StimulsoftDesignerComponent {
constructor(proxy, httpClient) {
this.proxy = proxy;
this.httpClient = httpClient;
/**
* Occurs when designer loaded
*/
this.designerLoaded = new EventEmitter();
this.id = 'aDesigner' + (Math.random() * 10000000).toString();
this.scriptLoading = false;
this.loaded = false;
}
ngOnDestroy() {
if (this.chartScripts) {
this.head.removeChild(this.chartScripts);
}
let options = this.designerEl.nativeElement?.firstChild?.jsObject?.options;
try {
clearTimeout(options.timerAjax);
}
catch { }
try {
clearTimeout(options.timerUpdateCache);
}
catch { }
try {
clearTimeout(options.timerAutoSave);
}
catch { }
}
ngOnInit() {
this.addScript();
}
ngOnChanges(changes) {
this.addScript();
}
addScript() {
if (this.scriptLoading)
return;
this.scriptLoading = true;
if (this.chartScripts) {
this.head.removeChild(this.chartScripts);
}
this.chartScripts = document.createElement('Script');
this.chartScripts.setAttribute('type', 'text/javascript');
this.head.appendChild(this.chartScripts);
let observable = this.httpClient.get(this.requestUrl, { responseType: 'text' }).pipe(catchError((error) => {
console.log(error);
this.scriptLoading = false;
return EMPTY;
}));
observable.subscribe(data => {
if (!this.loaded) {
try {
this.chartScripts.innerHTML = data;
const options = new Stimulsoft.Designer.StiDesignerOptions();
this.loaded = true;
setTimeout(() => {
this.scriptLoading = false;
});
this.showDesigner();
this.designerLoadedF();
}
catch {
this.scriptLoading = false;
}
}
});
}
designerLoadedF() {
let jsObject = this.designerEl.nativeElement?.firstChild?.jsObject;
if (!jsObject) {
setTimeout(() => {
this.designerLoadedF();
});
return;
}
this.designerLoaded.next(null);
}
showDesigner() {
const options = new Stimulsoft.Designer.StiDesignerOptions();
let defaultOptions = Stimulsoft?.Designer?.defaultOptions;
if (defaultOptions) {
for (let k in defaultOptions)
options[k] = defaultOptions[k];
options.useAliasesDictionary = defaultOptions.dictionary.useAliases;
}
if (this.width) {
options.width = this.width;
}
if (this.height) {
options.height = this.height;
}
this.designer = new Stimulsoft.Designer.StiDesigner(options, 'StiDesigner', false);
this.proxy.postParametersFunction_ = this.postParametersFunction;
this.designerEl.nativeElement.proxy = this.proxy;
this.designer.renderHtml(this.designerEl.nativeElement);
}
get head() {
return document.getElementsByTagName('head')[0];
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerComponent, deps: [{ token: ProxyService }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: StimulsoftDesignerComponent, selector: "stimulsoft-designer-angular", inputs: { requestUrl: "requestUrl", width: "width", height: "height", postParametersFunction: "postParametersFunction" }, outputs: { designerLoaded: "designerLoaded" }, providers: [ProxyService, FileSaverService], viewQueries: [{ propertyName: "designerEl", first: true, predicate: ["designer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
<div #designer [attr.id]="id">
<ng-content></ng-content>
</div>
`, isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerComponent, decorators: [{
type: Component,
args: [{ selector: 'stimulsoft-designer-angular', template: `
<div #designer [attr.id]="id">
<ng-content></ng-content>
</div>
`, providers: [ProxyService, FileSaverService] }]
}], ctorParameters: () => [{ type: ProxyService }, { type: i1.HttpClient }], propDecorators: { designerEl: [{
type: ViewChild,
args: ['designer']
}], designerLoaded: [{
type: Output
}], requestUrl: [{
type: Input
}], width: [{
type: Input
}], height: [{
type: Input
}], postParametersFunction: [{
type: Input
}] } });
class StimulsoftDesignerModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerModule, declarations: [StimulsoftDesignerComponent], imports: [CommonModule], exports: [StimulsoftDesignerComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StimulsoftDesignerModule, decorators: [{
type: NgModule,
args: [{
declarations: [StimulsoftDesignerComponent],
imports: [
CommonModule
],
exports: [StimulsoftDesignerComponent]
}]
}] });
/*
* Public API Surface of stimulsoft-designer-angular
*/
/**
* Generated bundle index. Do not edit.
*/
export { StimulsoftDesignerComponent, StimulsoftDesignerModule };
//# sourceMappingURL=stimulsoft-designer-angular.mjs.map