blob: bbbe640c51e1b1c1d403b0b046800afdb7c9a2ef [file] [log] [blame]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<template>
<div
class="we-toolbar-wrap">
<ul
ref="toolbar"
class="we-toolbar">
<li
v-if="(script.runType === 'sql' || script.runType === 'hql' ||(script.runType === 'py' && script.resultList[script.resultSet].result.type === '2')) && this.$route.name === 'Home' && script.resultList !== null">
<Poptip
:transfer="true"
:width="220"
v-model="popup.visualis"
placement="right"
popper-class="we-poptip">
<div @click.stop="showResultAction">
<Icon v-if="visualShow=='table'" type="md-analytics" :size="20"/>
<Icon v-if="visualShow=='visual' || visualShow=='dataWrangler'" type="ios-grid" :size="iconSize"/>
<span v-if="isIconLabelShow" :title="$t('message.common.toolbar.analysis')" class="v-toolbar-icon">{{ analysistext.text }}</span>
</div>
<div slot="content">
<div>
<Row>
{{$t('message.common.toolbar.model')}}
</Row>
<Row>
<RadioGroup v-model="resultsShowType">
<Col span="10">
<Radio label="1">{{$t('message.common.toolbar.graphAnalysis')}}</Radio>
</Col>
<Col
span="10"
offset="4">
<Radio label="2">{{$t('message.common.toolbar.excelAnalysis')}}</Radio>
</Col>
</RadioGroup>
</Row>
</div>
<Row class="confirm">
<Col span="10">
<Button @click="cancelPopup('visualis')">{{$t('message.common.cancel')}}</Button>
</Col>
<Col
span="10"
offset="4">
<Button
type="primary"
@click="confirm('visualis')">{{ $t('message.common.submit') }}</Button>
</Col>
</Row>
</div>
</Poptip>
</li>
<li v-if="analysistext.flag !== 2 && rsDownload && canDownload" :style="{cursor: rsDownload ? 'pointer': 'not-allowed'}">
<Poptip
:transfer="true"
:width="500"
v-model="popup.download"
placement="right"
popper-class="we-poptip">
<div @click.stop="openPopup('download')">
<i class="material-icons">cloud_download</i>
<span v-if="isIconLabelShow" :title="$t('message.common.download')" class="v-toolbar-icon">{{ $t('message.common.download') }}</span>
</div>
<div slot="content">
<div>
<Row>
{{ $t('message.common.toolbar.format') }}
</Row>
<Row>
<RadioGroup v-model="download.format">
<Col span="10">
<Radio label="1">CSV</Radio>
</Col>
<Col
v-if="resultType === '2'"
span="10"
offset="4">
<Radio label="2">Excel</Radio>
</Col>
</RadioGroup>
</Row>
</div>
<div>
<Row>
{{ $t('message.common.toolbar.coding') }}
</Row>
<Row>
<RadioGroup v-model="download.coding">
<Col span="10">
<Radio label="1">UTF-8</Radio>
</Col>
<Col
span="10"
offset="4">
<Radio label="2">GBK</Radio>
</Col>
</RadioGroup>
</Row>
</div>
<div>
<Row>
{{$t('message.common.toolbar.replace')}}
</Row>
<Row>
<RadioGroup v-model="download.nullValue">
<Col span="10">
<Radio label="1">NULL</Radio>
</Col>
<Col
span="10"
offset="4">
<Radio label="2">{{$t('message.common.toolbar.emptyString')}}</Radio>
</Col>
</RadioGroup>
</Row>
</div>
<div v-if="+download.format === 1">
<Row>
{{$t('message.common.toolbar.selectSeparator')}}
</Row>
<Row>
<RadioGroup v-model="download.csvSeparator" style="width: 100%;">
<Col v-for="item in separators" :key="item.value" :span="item.span" :offset="item.offset">
<Radio :label="item.value">{{item.label}}</Radio>
</Col>
</RadioGroup>
</Row>
</div>
<Row>
{{$t('message.common.toolbar.downloadMode')}}
</Row>
<div v-if="isAll">
<Row>
<Checkbox v-model="allDownload">{{$t('message.common.toolbar.all', {count: String(allPath.length)})}}</Checkbox>
</Row>
</div>
<div v-if="isExcel">
<Row>
<Checkbox v-model="autoFormat">{{$t('message.common.toolbar.autoFormat')}}</Checkbox>
</Row>
</div>
<Row class="confirm">
<Col span="10">
<Button @click="cancelPopup('download')">{{$t('message.common.cancel')}}</Button>
</Col>
<Col
span="10"
offset="4">
<Button
type="primary"
@click="confirm('download')">{{ $t('message.common.submit') }}</Button>
</Col>
</Row>
</div>
</Poptip>
</li>
<li
@click="openPopup('export')"
v-if="$route.name === 'Home' && analysistext.flag !== 2">
<SvgIcon :style="{ 'font-size': '20px' }" icon-class="common" color="#515a6e"/>
<span
class="v-toolbar-icon"
v-if="isIconLabelShow">{{ $t('message.common.toolbar.export') }}</span>
</li>
<li
@click="openPopup('rowView')"
v-if="row"
:title="$t('message.common.toolbar.rowToColumnTitle')">
<SvgIcon :style="{ 'font-size': '20px' }" icon-class="common" color="#515a6e"/>
<span v-if="isIconLabelShow" class="v-toolbar-icon">{{$t('message.common.toolbar.rowToColumn')}}</span>
</li>
<li
@click="openPopup('filter')"
:title="$t('message.common.toolbar.resultGroupLineFilter')"
v-if="showFilter">
<SvgIcon :style="{ 'font-size': '20px' }" icon-class="common" color="#515a6e"/>
<span
class="v-toolbar-icon"
v-if="isIconLabelShow">{{$t('message.common.toolbar.lineFilter')}}</span>
</li>
</ul>
<results-export
ref="exportToShare"
:script="script"
:dispatch="dispatch"
:current-path="currentPath">
</results-export>
<table-row
ref="tableRow"
:row="row">
</table-row>
</div>
</template>
<script>
import moment from 'moment';
import elementResizeEvent from '@/common/helper/elementResizeEvent';
import resultsExport from './resultsExport.vue';
import tableRow from './tableRow.vue';
import mixin from '@/common/service/mixin';
import api from '@/common/service/api';
import 'material-design-icons/iconfont/material-icons.css';
import storage from '@/common/helper/storage';
export default {
components: {
resultsExport,
tableRow,
},
mixins: [mixin],
props: {
visualShow: String,
currentPath: {
type: String,
default: '',
},
allPath: {
type: Array,
default: () => []
},
showFilter: {
type: Boolean,
default: false
},
script: [Object],
row: {
type: Array,
default: () => [],
},
dispatch: {
type: Function,
required: true
},
getResultUrl: {
type: String,
defalut: `filesystem`
},
resultType: {
type: String,
defalut: ''
},
comData: {
type: Object
}
},
data() {
return {
popup: {
download: false,
export: false,
visual: false,
rowView: false,
visualis: false
},
download: {
format: '1',
coding: '1',
nullValue: '1',
csvSeparator: '1',
},
isIconLabelShow: true,
iconSize: 14,
allDownload: false, // whether to download all result sets(是否下载全部结果集)
autoFormat: false, // whether to format result sets
resultsShowType: '2',
separators: [
{ key: ',', label: this.$t('message.common.separator.comma'), value: '1', span: 4, offset: 0},
{ key: '\t', label: this.$t('message.common.separator.tab'), value: '2', span: 4, offset: 1},
{ key: ' ', label: this.$t('message.common.separator.space'), value: '3', span: 4, offset: 1},
{ key: '|', label: this.$t('message.common.separator.vertical'), value: '4', span: 4, offset: 1 },
{ key: ';', label: this.$t('message.common.separator.semicolon'), value: '5', span: 4, offset: 1}
]
};
},
computed: {
analysistext: function(){
let describe = '';
this.visualShow === "table"? describe = {
flag: 1,
text: this.$t('message.common.toolbar.deepAnalysis')
} : describe = {
flag: 2,
text: this.$t('message.common.toolbar.resultGroup')
};
return describe
},
canDownload() {
if (this?.script?.resultList && this.script.resultList[this.script.resultSet]?.result?.tipMsg) {
return !this.script.resultList[this.script.resultSet].result.tipMsg;
}
return true
},
isAll() {
return ['hql', 'sql', 'tsql', 'nebula'].includes(this.script.runType) || this.download.format === '1';
},
isExcel() {
return this.download.format === '2';
},
rsDownload() {
return storage.get('resultSetExportEnable');
}
},
mounted() {
elementResizeEvent.bind(this.$el, this.resize);
},
methods: {
openPopup(type) {
if (type === 'download') {
this.download = {
format: '1',
coding: '1',
nullValue: '1',
csvSeparator: '1',
}
}
if (type === 'export') {
this.$refs.exportToShare.open();
} else if (type === 'rowView') {
this.$refs.tableRow.open();
} else if (type === 'filter') {
this.$emit('on-filter');
} else {
this.popup[type] = true;
}
},
cancelPopup(type) {
this.popup[type] = false;
},
confirm(type) {
this[`${type}Confirm`]();
this.cancelPopup(type);
},
showResultAction() {
// When toggling the result set visualization button(当切换结果集可视化按钮时)
if (this.visualShow=='table') {
this.popup.visualis = true;
} else {
this.$emit('on-analysis', 'table');
}
},
visualisConfirm() {
const resultType = this.resultsShowType === '1' ? 'visual' : 'dataWrangler';
this.$emit('on-analysis', resultType);
},
downloadFromHref(url) {
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', '');
const evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, true, false, 0, null);
return link.dispatchEvent(evObj)
},
pause(msec = 1000) {
return new Promise((resolve) => {
setTimeout(resolve, msec);
})
},
async downloadConfirm() {
const splitor = this.download.format === '1' ? 'csv' : 'xlsx';
const charset = this.download.coding === '1' ? 'utf-8' : 'gbk';
const nullValue = this.download.nullValue === '1' ? 'NULL' : 'BLANK';
const timestamp = moment.unix(moment().unix()).format('MMDDHHmm');
let fileName = ''
if (this.$route.query.fileName && this.$route.query.fileName !== 'undefined') {
fileName = this.$route.query.fileName
} else if ( this.script.fileName && this.script.fileName !== 'undefined') {
fileName = this.script.fileName
} else if(this.script.title && this.script.title !== 'undefined') {
fileName = this.script.title
}
const filename = `Result_${fileName}_${timestamp}`;
let temPath = this.currentPath;
// The result set path of the api execution download is different(api执行下载的结果集路径不一样)
let apiPath = `${this.getResultUrl}/resultsetToExcel`;
if (this.isAll && this.allDownload && this.isExcel) {
temPath = temPath.substring(0, temPath.lastIndexOf('/'));
apiPath = `${this.getResultUrl}/resultsetsToExcel`
}
let url = `http://${window.location.host}/api/rest_j/v1/` + apiPath + '?charset=' + charset + '&outputFileType=' + splitor + '&nullValue=' + nullValue;
// If the api execution page gets the result set, you need to bring the taskId(如果是api执行页获取结果集,需要带上taskId)
if(this.getResultUrl !== 'filesystem') {
url += `&taskId=${this.comData.taskID}`
}
if (+this.download.format === 1) {
let separatorItem = this.separators.find(item => item.value === this.download.csvSeparator) || {};
let separator = encodeURIComponent(separatorItem.key || '');
url += `&csvSeparator=${separator}`
}
if(this.isExcel) {
url += `&autoFormat=${this.autoFormat}`
}
// Before downloading, use the heartbeat interface to confirm whether to log in(下载之前条用心跳接口确认是否登录)
await api.fetch('/user/heartbeat', 'get');
const eventList = [];
let flag = null;
if (this.isAll && !this.isExcel && this.allDownload) {
let count = 0
for(let [index, path] of this.allPath.sort((a, b) => {
return +(a.split('.')[0].substring(1)) - +(b.split('.')[0].substring(1))
}).entries()) {
let temUrl = url;
temUrl += `&path=${path}`
const name = `ResultSet${index + 1}`
temUrl += '&outputFileName=' + name
const event = this.downloadFromHref(temUrl)
eventList.push(event);
if(++count >= 10) {
await this.pause(1000);
count = 0;
}
}
// this.allPath.forEach(path => {
// let temUrl = url;
// temUrl += `&path=${path}`
// const name = `ResultSet${Number(path.substring(temPath.lastIndexOf('/')).split('.')[0].split('_')[1]) + 1}`
// temUrl += '&outputFileName=' + name
// const event = this.downloadFromHref(temUrl)
// eventList.push(event);
// });
} else {
url += `&path=${temPath}` + '&outputFileName=' + filename
flag = this.downloadFromHref(url);
}
this.$nextTick(() => {
if (flag && this.isExcel) {
this.$Message.success(this.$t('message.common.toolbar.success.download'));
} else if (!this.isExcel && !eventList.includes(false)) {
this.$Message.success(this.$t('message.common.toolbar.success.download'));
}
});
},
// analysis() {
// this.$emit('on-analysis');
// },
resize() {
const height = window.getComputedStyle(this.$refs.toolbar).height;
if (parseInt(height) <= 190) {
this.isIconLabelShow = false;
this.iconSize = 20;
} else {
this.isIconLabelShow = true;
this.iconSize = 14;
}
}
},
beforeDestroy() {
elementResizeEvent.unbind(this.$el, this.resize);
},
};
</script>
<style lang="scss" scoped>
@import '@/common/style/variables.scss';
.we-toolbar-wrap {
width: $toolbarWidth;
height: 100%;
word-break: break-all;
position: $absolute;
left: 40px;
margin-left: -$toolbarWidth;
background: $body-background;
.we-poptip {
padding: 12px;
line-height: 28px;
.confirm {
margin-top: 10px;
}
.title {
margin: 10px 0;
text-align: center;
}
}
.we-toolbar {
width: 100%;
height: 100%;
border-right: 1px solid #dcdee2;
padding-top: 10px;
li {
padding-bottom: 20px;
text-align: center;
cursor: pointer;
}
span {
display: block;
line-height: 24px
}
}
}
</style>