Skip to content

Commit

Permalink
#234 download csv for schedule record
Browse files Browse the repository at this point in the history
  • Loading branch information
brookshi committed Jul 25, 2018
1 parent b1e6863 commit 6611420
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 113 deletions.
192 changes: 109 additions & 83 deletions client/src/modules/schedule/schedule_run_history_grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,94 +126,120 @@ class ScheduleRunHistoryGrid extends React.Component<ScheduleRunHistoryGridProps
});

return (
<RunResultTable
className="schedule-sub-table"
bordered={true}
size="small"
rowKey="key"
onChange={(pagination, filters, sorter) => { this.setState({ ...this.state, isFilter: filters && filters['success'] && filters['success'].length > 0 }); }}
dataSource={displayRunResults}
pagination={false}
>
<RunResultColumn
title={Msg('Common.Name')}
dataIndex="id"
render={(text, runResult) => ({ children: this.getRecordDisplayName(runResult.id), props: { rowSpan: runResult.rowSpan } })}
/>
<RunResultColumn
title={Msg('Schedule.Param')}
dataIndex="param"
render={text => this.getParamDisplay(text)}
/>
<RunResultColumn
title={Msg('Schedule.Pass')}
dataIndex="success"
render={(text, runResult) => <Tag color={this.isSuccess(runResult) ? successColor : failColor}>{this.isSuccess(runResult) ? pass() : fail()}</Tag>}
filters={[{
text: pass(),
value: 'true',
}, {
text: fail(),
value: 'false',
}]}
onFilter={(value, runResult) => this.isSuccess(runResult).toString() === value}
/>
<RunResultColumn
title={Msg('Schedule.Duration')}
dataIndex="duration"
render={(text, runResult) => `${runResult.elapsed / 1000} s`}
/>
<RunResultColumn
title={Msg('Common.Environment')}
dataIndex="envId"
render={(text, runResult) => this.getEnvName(runResult.envId)}
/>
<RunResultColumn title={Msg('Schedule.Headers')} dataIndex="headers" render={this.getHeadersDisplay} />
<RunResultColumn title={Msg('Schedule.Body')} dataIndex="body" render={this.getBodyDisplay} />
<RunResultColumn title={Msg('Schedule.Tests')} dataIndex="tests" render={this.getTestsDisplay} />
{
record.result.compare.length === 0 ? '' : (
<div className="schedule-subtable">
<Button
className="icon-btn excel-btn"
type="primary"
icon="download"
onClick={() => this.generateExcel(displayRunResults, record.runDate)}
>
CSV
</Button>
<div id="schedule-record-table">
<RunResultTable
className="schedule-sub-table"
bordered={true}
size="small"
rowKey="key"
onChange={(pagination, filters, sorter) => { this.setState({ ...this.state, isFilter: filters && filters['success'] && filters['success'].length > 0 }); }}
dataSource={displayRunResults}
pagination={false}
>
<RunResultColumn
title={Msg('Schedule.Compare')}
dataIndex="compareResult"
key="compareResult"
render={(text, runResult) => ({
children: (
<div>
<div className={runResult.compareResult !== notMatch() ? 'schedule-success' : 'schedule-failed'}>{runResult.compareResult}</div>
{
runResult.isOrigin && runResult.compareResult === notMatch() ? (
<Button
className="tab-extra-button"
ghost={true}
onClick={() => {
const compareRunResult = displayRunResults.find(r => r.key === `${runResult.key}c`);
if (!compareRunResult) { return; }
const contentType = StringUtil.getContentTypeFromHeaders(runResult.headers);
this.setState({
...this.state,
isDiffDlgOpen: true,
diffOriginTitle: `${this.getRecordDisplayName(runResult.id)}(${this.getEnvName(runResult.envId)})`,
diffOriginContent: this.getDiffContent(runResult.export, runResult.body, contentType),
diffTargetTitle: `${this.getRecordDisplayName(compareRunResult.id)}(${this.getEnvName(compareRunResult.envId)})`,
diffTargetContent: this.getDiffContent(compareRunResult.export, compareRunResult.body, contentType),
});
}}
>
{Msg('Schedule.ViewDiff')}
</Button>
) : ''
}
</div>
), props: { rowSpan: runResult.rowSpan }
})}
title={Msg('Common.Name')}
dataIndex="id"
render={(text, runResult) => ({ children: this.getRecordDisplayName(runResult.id), props: { rowSpan: runResult.rowSpan } })}
/>
)
}
</RunResultTable>
<RunResultColumn
title={Msg('Schedule.Param')}
dataIndex="param"
render={text => this.getParamDisplay(text)}
/>
<RunResultColumn
title={Msg('Schedule.Pass')}
dataIndex="success"
render={(text, runResult) => <Tag color={this.isSuccess(runResult) ? successColor : failColor}>{this.isSuccess(runResult) ? pass() : fail()}</Tag>}
filters={[{
text: pass(),
value: 'true',
}, {
text: fail(),
value: 'false',
}]}
onFilter={(value, runResult) => this.isSuccess(runResult).toString() === value}
/>
<RunResultColumn
title={Msg('Schedule.Duration')}
dataIndex="duration"
render={(text, runResult) => `${runResult.elapsed / 1000} s`}
/>
<RunResultColumn
title={Msg('Common.Environment')}
dataIndex="envId"
render={(text, runResult) => this.getEnvName(runResult.envId)}
/>
<RunResultColumn title={Msg('Schedule.Headers')} dataIndex="headers" render={this.getHeadersDisplay} />
<RunResultColumn title={Msg('Schedule.Body')} dataIndex="body" render={this.getBodyDisplay} />
<RunResultColumn title={Msg('Schedule.Tests')} dataIndex="tests" render={this.getTestsDisplay} />
{
record.result.compare.length === 0 ? '' : (
<RunResultColumn
title={Msg('Schedule.Compare')}
dataIndex="compareResult"
key="compareResult"
render={(text, runResult) => ({
children: (
<div>
<div className={runResult.compareResult !== notMatch() ? 'schedule-success' : 'schedule-failed'}>{runResult.compareResult}</div>
{
runResult.isOrigin && runResult.compareResult === notMatch() ? (
<Button
className="tab-extra-button"
ghost={true}
onClick={() => {
const compareRunResult = displayRunResults.find(r => r.key === `${runResult.key}c`);
if (!compareRunResult) { return; }
const contentType = StringUtil.getContentTypeFromHeaders(runResult.headers);
this.setState({
...this.state,
isDiffDlgOpen: true,
diffOriginTitle: `${this.getRecordDisplayName(runResult.id)}(${this.getEnvName(runResult.envId)})`,
diffOriginContent: this.getDiffContent(runResult.export, runResult.body, contentType),
diffTargetTitle: `${this.getRecordDisplayName(compareRunResult.id)}(${this.getEnvName(compareRunResult.envId)})`,
diffTargetContent: this.getDiffContent(compareRunResult.export, compareRunResult.body, contentType),
});
}}
>
{Msg('Schedule.ViewDiff')}
</Button>
) : ''
}
</div>
), props: { rowSpan: runResult.rowSpan }
})}
/>
)
}
</RunResultTable>
</div>
</div>
);
}

private generateExcel = (displayRunResults: Array<DisplayRunResult>, runDate: Date) => {
const { schedule } = this.props;
const rows = displayRunResults.map(d => ([
this.getRecordDisplayName(d.id),
d.param || '',
this.getEnvName(d.envId),
this.isSuccess(d).toString(),
`${d.elapsed / 1000} s`,
JSON.stringify(d.tests)
]));
const headers = ['Name', 'Parameter', 'Environment', 'Pass', 'Duration', 'Tests'];
StringUtil.downloadCSV(headers, rows, `${schedule.name}-${(runDate || new Date()).toLocaleString()}`);
}

private compareExport(originRst: RunResult, compareRst: RunResult): boolean {
if (originRst.export !== defaultExport &&
compareRst.export !== defaultExport) {
Expand Down
27 changes: 27 additions & 0 deletions client/src/modules/schedule/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@
}
}

.schedule-subtable{
position: relative;
}

div .excel-btn{
right: 10px;
top: 4px;
z-index: 1;
font-size: 13px;
background: transparent;

&:hover{
background: transparent;
color: #2c9ef0;
}

&:active{
background: transparent;
color: #0479cc;
}

&:focus{
background: transparent;
color: #0479cc;
}
}

.schedule-success{
color: #87d068;
}
Expand Down
31 changes: 1 addition & 30 deletions client/src/modules/stress_test/stress_run_diagram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,32 +281,6 @@ class StressRunDiagram extends React.Component<StressRunDiagramProps, StressRunD
};
}

private getTableHtml = () => {
const tableDiv = document.getElementById('stress-table');
const defaultTable = '<table />';

if (!tableDiv) {
return defaultTable;
}
const findTable: (parent: Element) => (Element | undefined) = (parent: Element) => {
if (parent.tagName.toLowerCase() === 'table') {
return parent;
}
if (!parent.children) {
return undefined;
}
for (let i = 0; i < parent.children.length; i++) {
const table = findTable(parent.children.item(i));
if (table) {
return table;
}
}
return undefined;
};
const table = findTable(tableDiv);
return table ? table.outerHTML : defaultTable;
}

private getNameDisplay = (value: any) => {
return (
<span>
Expand Down Expand Up @@ -382,10 +356,7 @@ class StressRunDiagram extends React.Component<StressRunDiagramProps, StressRunD

private generateExcel = () => {
const { name, runDate } = this.props;
var link = document.createElement('a');
link.download = `${name}-${(runDate || new Date()).toLocaleString()}.xls`;
link.href = StringUtil.toBase64Excel(this.getTableHtml());
link.click();
StringUtil.downloadTable('stress-table', `${name}-${(runDate || new Date()).toLocaleString()}`);
}

public render() {
Expand Down
44 changes: 44 additions & 0 deletions client/src/utils/string_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,4 +321,48 @@ export class StringUtil {
return obj.toString();
}
}

static findTableHtml = (id: string) => {
const tableDiv = document.getElementById(id);
const defaultTable = '<table />';

if (!tableDiv) {
return defaultTable;
}
const findTable: (parent: Element) => (Element | undefined) = (parent: Element) => {
if (parent.tagName.toLowerCase() === 'table') {
return parent;
}
if (!parent.children) {
return undefined;
}
for (let i = 0; i < parent.children.length; i++) {
const table = findTable(parent.children.item(i));
if (table) {
return table;
}
}
return undefined;
};
const table = findTable(tableDiv);
return table ? table.outerHTML : defaultTable;
}

static downloadTable = (id: string, name: string) => {
const link = document.createElement('a');
link.download = `${name}.xls`;
link.href = StringUtil.toBase64Excel(StringUtil.findTableHtml(id));
link.click();
}

static downloadCSV = (header: Array<string>, datas: Array<any>, name: string) => {
const csv = [header, ...datas].map((row, index) => row.map((element) => '\"' + (element || '').replace(/"/g, `""`) + '\"').join(',')).join(`\n`);
const blob = new Blob(['', csv], { type: 'text/csv' });
const dataURI = `data:text/csv;charset=utf-8,${csv}`;
const url = (typeof URL.createObjectURL === 'undefined') ? dataURI : URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = `${name}.csv`;
link.href = url;
link.click();
}
}

0 comments on commit 6611420

Please sign in to comment.