import { HttpBackend, HttpClient, HttpHeaders } from "@angular/common/http";
import { AppContext } from "../../components/app-context/app.context";
import { TranslateService } from "@ngx-translate/core";
import { CustomNotificationService } from "../../components/notification/customnotification.service";
import { WebsocketService } from "../../components/services/websocket.service";
import { map, take } from "rxjs/operators";
import {
IgxExcelExporterService,
IgxExcelExporterOptions,
IgxCsvExporterService,
IgxCsvExporterOptions,
CsvFileTypes,
IColumnExportingEventArgs,
} from "@infragistics/igniteui-angular";
import { Injectable } from "@angular/core";
import { uuid } from "../configuration/app.service";
import { Attributes } from "../../components/edit-attribute";
declare const contextPath: string;
interface ExportRequest {
exportId: string;
data: any[];
headers: string[];
fields: string[];
settings: any;
title: string;
}
@Injectable()
export class DataListExportService {
protected httpClient: HttpClient;
protected _exportPath: string = "/api/core/exports";
constructor(
protected httpBackend: HttpBackend,
protected appContext: AppContext,
protected translateService: TranslateService,
protected notificationService: CustomNotificationService,
protected websocketService: WebsocketService,
protected http: HttpClient,
protected excelExportService: IgxExcelExporterService,
private csvExportService: IgxCsvExporterService
) {
this.httpClient = new HttpClient(httpBackend);
}
set exportPath(exportPath: string) {
this._exportPath = exportPath;
}
export(grid, settings, title, useIgxExport, cachedData) {
if (settings) {
let format = settings.exportFormat.toLowerCase();
let download = settings.download || false;
const fields = grid.columnList["_results"].map((h) => h.field);
const headers = grid.columnList["_results"].map((h) => h.header);
const rows = [];
let rowIdx = 0;
let exportData = cachedData ? cachedData : grid.data;
for (let i = 0; i < exportData.length; i++) {
const gridRow = exportData[i];
const columns = [];
const identifier = gridRow[grid.primaryKey];
const skip =
settings.onlySelectedRows &&
grid.selectedRows.indexOf(identifier) == -1;
if (skip) {
continue;
}
for (let fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) {
columns[fieldIdx] = "";
const field = fields[fieldIdx];
const rowValue = Attributes.rowFieldOrAttribute(gridRow, field);
if (!rowValue && rowValue !== 0) {
continue;
}
let value = rowValue;
if (field == "main-asset") {
if (!rowValue?._links?.[settings.assetFormat]) {
continue;
}
value = rowValue._links[settings.assetFormat].href;
} else if (Attributes.isValueField(field)) {
value = Attributes.formatAttribute(rowValue, {
type: "string",
ignoreSeconds: true,
});
}
columns[fieldIdx] = value || value === 0 ? value.toString() : "";
}
rows[rowIdx++] = columns;
}
const exportId = uuid();
const request: ExportRequest = {
exportId,
data: rows,
headers,
fields,
settings,
title: this.translateService.instant(title),
};
if (useIgxExport) {
this.exportListUsingIgx(grid, request);
return;
}
this.websocketService
.createSub(`/topic/list/export/${exportId}`, () => {
this.http
.post<any>(`${this._exportPath}/${format}`, request)
.subscribe((response) => {
this.notificationService.create(
response.title,
response.message,
response.level
);
});
})
.pipe(
map((data) => {
return JSON.parse(data.body);
}),
take(1)
)
.subscribe((data) => {
this.notificationService.create(data.title, data.message, data.level);
if (download && data.downloadUri) {
this.download(data.downloadUri, request);
}
});
}
}
exportListUsingIgx(grid, request) {
if (request.settings.exportFormat === "CSV") {
this.csvExportService.columnExporting.subscribe(
(args: IColumnExportingEventArgs) => {
args.header = request.headers[args.columnIndex];
}
);
const exportOptions = new IgxCsvExporterOptions(
request.title,
CsvFileTypes.CSV
);
exportOptions.valueDelimiter = request.settings.csvSeparator;
this.csvExportService.exportData(request.data, exportOptions);
} else {
const exportOptions = new IgxExcelExporterOptions(request.title);
exportOptions.exportAsTable = false;
this.excelExportService.columnExporting.subscribe(
(args: IColumnExportingEventArgs) => {
args.header = request.headers[args.columnIndex];
}
);
this.excelExportService.exportData(request.data, exportOptions);
}
}
download(uri: string, request: ExportRequest) {
const isChrome = window.navigator.userAgent.indexOf("Chrome") > -1;
if (isChrome) {
//This will kill websocket connections in firefox do not use this in firefox!
//https://stackoverflow.com/questions/42340698/change-window-location-href-in-firefox-without-closing-websockets
window.location.href = contextPath + uri;
return;
}
// For some reason I dont understand this will show "Error - Servererror" when downloading the file in chrome but still download it correctly..
// Works fine in IE & firefox so just check if we are in chrome
var a = document.createElement("a");
document.body.appendChild(a);
a.style.display = "none";
a.href = contextPath + uri;
a.download = request.title;
a.click();
setTimeout(() => {
document.body.removeChild(a);
}, 200);
}
}