Skip to content

Commit

Permalink
[front: editLogs] export as xls
Browse files Browse the repository at this point in the history
  • Loading branch information
t8g committed Sep 26, 2017
1 parent 1d4971f commit 99b0b02
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 29 deletions.
90 changes: 71 additions & 19 deletions client/src/app/isari-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,14 @@ export class IsariDataService {
// if path = [grades, grade] we get _get(schema, 'grades') then _get(schema, 'grades.grade') and we store the labels
_label: diff.path.reduce((a, v, i, s) => [...a, this.getLabel(schema, [...s.slice(0, i), v].join('.'), lang)], []).join(' : ')
});
if (diff.valueBefore) res._beforeLabelled$ = this.formatWithRefs(this.key2label(diff.valueBefore, diff.path, schema, lang));
if (diff.valueAfter) res._afterLabelled$ = this.formatWithRefs(this.key2label(diff.valueAfter, diff.path, schema, lang));
if (diff.valueBefore) {
res._beforeLabelled$ = this.formatWithRefs(this.key2label(diff.valueBefore, diff.path, schema, lang))
.catch(() => Observable.of('ref. not found'));
}
if (diff.valueAfter) {
res._afterLabelled$ = this.formatWithRefs(this.key2label(diff.valueAfter, diff.path, schema, lang))
.catch(() => Observable.of('ref. not found'));
}
return res;
});

Expand Down Expand Up @@ -188,15 +194,15 @@ export class IsariDataService {
if (obj.value && obj.ref) return this.getForeignLabel(obj.ref, obj.value).map(x => x[0].value);

const format = (o, refs, level = 0) => {
if (isArray(o)) return o.map(oo => format(oo, refs, level)).join("\r\n---\r\n");
if (isArray(o)) return o.map(oo => format(oo, refs, level)).join("\n---\n");

return Object.keys(o)
.reduce((s, k) => {
s += `${' '.repeat(level)}${k} : `;
if (typeof o[k] === 'string') s += o[k];
else if (o[k].ref && o[k].value) s += o[k].value.length === 0 ? '[]' : (refs[o[k].value] || '????');
else s += "\r\n" + format(o[k], refs, level + 1);
return s + "\r\n";
else s += "\n" + format(o[k], refs, level + 1);
return s + "\n";
}, "");
}

Expand All @@ -222,23 +228,63 @@ export class IsariDataService {

}

exportLogs(logs, feature, labs$, translate, details) {
exportLogs(logs, feature, labs$, translate, details, filetype) {

const linebreak = filetype === "xls" ? "\n" : "\r\n";

const exportFile = {
csv(data) {
const csvString = Papa.unparse(data);
const blob = new Blob([csvString], {type: CSV_MIME});
saveAs(blob, `editlogs.csv`);
},
xlsx(data) {
const opts = { bookType: 'xlsx', bookSST: true, type: 'binary' };
const workbook = { Sheets: {Sheet1: null}, SheetNames: ['Sheet1'] };
const sheet = {};
const range = {s: {c: Infinity, r: Infinity}, e: {c: -Infinity, r: -Infinity}};

for (let R = 0, l = data.length; R < l; R++) {
const line = data[R];
let C = 0;
for (const k in line) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
const value = line[k];
const address = XLSX.utils.encode_cell({c: C, r: R});
const cell = {v: value};
sheet[address] = cell;
C++;
}
}

sheet['!ref'] = XLSX.utils.encode_range(range);
workbook.Sheets.Sheet1 = sheet;
const xlsx = XLSX.write(workbook, opts);
const buffer = new ArrayBuffer(xlsx.length);
const view = new Uint8Array(buffer);

for (let i = 0, l = xlsx.length; i !== l; i++) {
view[i] = xlsx.charCodeAt(i) & 0xFF;
}

function csv(data) {
const csvString = Papa.unparse(data);
const blob = new Blob([csvString], {type: CSV_MIME});
saveAs(blob, `editlogs.csv`);
const blob = new Blob([buffer], {type: XLSX_MIME});
saveAs(blob, 'editlogs.xlsx');

}
}

function getRow(log, feature, translations, labs, diff = null, pos = 0, values = []) {
const res = {
[translations['editLogs.date']]: (new DatePipe('fr-FR')).transform(log.date, 'yyyy-MM-dd HH:mm'),
[translations['editLogs.object.' + feature]]: log.item.name,
[translations['editLogs.action']]: log.action,
[translations['editLogs.fields']]: log._labels.join('\r\n'),
[translations['editLogs.fields']]: log._labels.join(linebreak),
[translations['editLogs.who']]: log.who.name,
[translations['editLogs.lab']]: log.who.roles.map(role => role.lab ? labs[role.lab].value : '').join('\r\n'),
[translations['editLogs.role']]: log.who.roles.map(role => role._label).join('\r\n'),
[translations['editLogs.lab']]: log.who.roles.map(role => role.lab ? labs[role.lab].value : '').join(linebreak),
[translations['editLogs.role']]: log.who.roles.map(role => role._label).join(linebreak),
};
if (!diff) return res;

Expand All @@ -260,10 +306,16 @@ export class IsariDataService {
if (details) {
// Je suis navré pour ce qui va suivre

const logs$ = logs.reduce((acc1, log) => [
const logs$ = logs.reduce((acc1, log) => {
return [
...acc1,
...log.diff.reduce((acc2, diff) => [...acc2, (diff._beforeLabelled$ || Observable.of('')), (diff._afterLabelled$ || Observable.of(''))], [])
], []);
...log.diff.reduce((acc2, diff) => {
const before$ = diff._beforeLabelled$ || Observable.of('');
const after$ = diff._afterLabelled$ || Observable.of('');
return [...acc2, before$, after$]
}, [])
]
}, []);

// RxJS FTW ?!
Observable.combineLatest([
Expand All @@ -276,7 +328,7 @@ export class IsariDataService {
labs$
])
.subscribe(([values, translations, labs]) => {
csv(logs.reduce((d, log) => [
exportFile[filetype](logs.reduce((d, log) => [
...d,
...log.diff.map((diff, j) => getRow(log, feature, translations, labs, diff, d.length + j, values))
], []));
Expand All @@ -288,7 +340,7 @@ export class IsariDataService {
labs$
])
.subscribe(([translations, labs]) => {
csv(logs.map(log => getRow(log, feature, translations, labs)));
exportFile[filetype](logs.map(log => getRow(log, feature, translations, labs)));
})
}
}
Expand Down Expand Up @@ -476,7 +528,7 @@ export class IsariDataService {

if (!this.labelsCache[url]) {
this.labelsCache[url] = this.http.get(url, this.getHttpOptions())
.map(response => response.json());
.map(response => response.json())
}

return this.labelsCache[url];
Expand Down
2 changes: 1 addition & 1 deletion client/src/app/isari-editor/isari-editor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
[labs]="labs$ | async"
[options]="options"
[hideItemCol]="true"
(onDownloadCSV)="downloadCSV($event)"
(onExport)="exportLogs($event)"
(onOptionsChange)="changeOpt($event)"
(onDetailsToggle)="toggleDetails()"></isari-log-table>

Expand Down
4 changes: 2 additions & 2 deletions client/src/app/isari-editor/isari-editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ export class IsariEditorComponent implements OnInit {
this.details$.next(!this.details$.value);
}

downloadCSV(logs) {
this.isariDataService.exportLogs(logs, this.feature, this.labs$, this.translate, this.details$.value);
exportLogs({logs, filetype}) {
this.isariDataService.exportLogs(logs, this.feature, this.labs$, this.translate, this.details$.value, filetype);
}

}
2 changes: 1 addition & 1 deletion client/src/app/isari-logs/isari-logs.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[data]="logs$ | async"
[labs]="labs$ | async"
[options]="options"
(onDownloadCSV)="downloadCSV($event)"
(onExport)="exportLogs($event)"
(onOptionsChange)="changeOpt($event)"
(onDetailsToggle)="toggleDetails()"></isari-log-table>

Expand Down
4 changes: 2 additions & 2 deletions client/src/app/isari-logs/isari-logs.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ export class IsariLogsComponent implements OnInit {
this.details$.next(!this.details$.value);
}

downloadCSV(logs) {
this.isariDataService.exportLogs(logs, this.feature, this.labs$, this.translate, this.details$.value);
exportLogs({logs, filetype}) {
this.isariDataService.exportLogs(logs, this.feature, this.labs$, this.translate, this.details$.value, filetype);
}

}
6 changes: 5 additions & 1 deletion client/src/app/log-table/log-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@

<span class="filer"></span>

<button md-raised-button (click)="downloadCSV()">CSV</button>
<button md-raised-button [md-menu-trigger-for]="menu">{{ 'download_select' | translate }}</button>
<md-menu #menu="mdMenu">
<button md-menu-item (click)="export('xlsx')">{{ 'download_excel_table' | translate}}</button>
<button md-menu-item (click)="export('csv')">{{ 'download_csv_table' | translate}}</button>
</md-menu>

</md-toolbar>

Expand Down
9 changes: 6 additions & 3 deletions client/src/app/log-table/log-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class LogTableComponent implements OnInit, OnChanges {
@Input() hideItemCol: boolean = false;
@Output() onOptionsChange = new EventEmitter();
@Output() onDetailsToggle = new EventEmitter();
@Output() onDownloadCSV = new EventEmitter();
@Output() onExport = new EventEmitter();

constructor(
private translate: TranslateService,
Expand Down Expand Up @@ -158,8 +158,11 @@ export class LogTableComponent implements OnInit, OnChanges {
this.onDetailsToggle.emit();
}

downloadCSV() {
this.onDownloadCSV.emit(this.data.logs);
export(filetype) {
this.onExport.emit({
logs: this.data.logs,
filetype
});
}

private emitOptions(options) {
Expand Down

0 comments on commit 99b0b02

Please sign in to comment.