Merge branch 'dev-2.0' of https://git.mesalab.cn/nezha/nezha-fronted into dev-2.0
This commit is contained in:
1756
nezha-fronted/package-lock.json
generated
1756
nezha-fronted/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@
|
|||||||
"element-ui": "^2.13.0",
|
"element-ui": "^2.13.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"leaflet": "^1.7.1",
|
"leaflet": "^1.7.1",
|
||||||
|
"moment-timezone": "^0.5.33",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"pl-table": "^2.5.8",
|
"pl-table": "^2.5.8",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
|
|||||||
@@ -192,7 +192,7 @@
|
|||||||
.right-box-select-dropdown {
|
.right-box-select-dropdown {
|
||||||
width: 625px;
|
width: 625px;
|
||||||
}
|
}
|
||||||
.limit-height {
|
.limit-height .el-cascader-menu {
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<el-dropdown trigger="click" class="nz-chart-top" :key="'chartDropdown'+chartIndex" v-clickoutside="clickos" :class="{'move-able':!isLock}">
|
<el-dropdown trigger="click" class="nz-chart-top" :key="'chartDropdown'+chartIndex" v-clickoutside="clickos" :class="{'move-able':!isLock}">
|
||||||
<el-dropdown-menu style="display: none"></el-dropdown-menu>
|
|
||||||
<span class="el-dropdown-link chart-title">
|
<span class="el-dropdown-link chart-title">
|
||||||
<span class="chart-title-text">{{chartData.name}}</span>
|
<span class="chart-title-text">{{chartData.name}}</span>
|
||||||
<span class="chart-title-icon" v-if="from !== 'chartTemp'" :class="{'visible':caretShow,'hidden':!caretShow}">
|
<span class="chart-title-icon" v-if="from !== 'chartTemp'" :class="{'visible':caretShow,'hidden':!caretShow}">
|
||||||
|
|||||||
@@ -263,14 +263,12 @@ export default {
|
|||||||
iframe.attachEvent('onload', function () {
|
iframe.attachEvent('onload', function () {
|
||||||
// iframe加载完毕以后执行操作
|
// iframe加载完毕以后执行操作
|
||||||
that.firstShow = true
|
that.firstShow = true
|
||||||
// console.log('iframe已加载完毕');
|
|
||||||
that.endLoading('screen')
|
that.endLoading('screen')
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
iframe.onload = function () {
|
iframe.onload = function () {
|
||||||
// iframe加载完毕以后执行操作
|
// iframe加载完毕以后执行操作
|
||||||
that.firstShow = true
|
that.firstShow = true
|
||||||
// console.log('iframe已加载完毕');
|
|
||||||
that.endLoading('screen')
|
that.endLoading('screen')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ import textChart from './text-chart'
|
|||||||
import chartPie from './chart-pie'
|
import chartPie from './chart-pie'
|
||||||
import chartBarStatis from './chart-bar-statistics'
|
import chartBarStatis from './chart-bar-statistics'
|
||||||
import chartTempData from '@/components/charts/chartTempData'
|
import chartTempData from '@/components/charts/chartTempData'
|
||||||
import {fromRoute} from "@/components/common/js/constants";
|
import { fromRoute } from '@/components/common/js/constants'
|
||||||
// import visNetwork from './visNetwork'
|
// import visNetwork from './visNetwork'
|
||||||
export default {
|
export default {
|
||||||
name: 'chartList',
|
name: 'chartList',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chartBox {
|
.chartBox {
|
||||||
float:left;
|
float:left;
|
||||||
padding: 0 0 10px 0;
|
padding: 0 10px 10px 0;
|
||||||
position:relative;
|
position:relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -361,18 +361,13 @@ export default {
|
|||||||
chartTitle.style.background = '#d8dce1'
|
chartTitle.style.background = '#d8dce1'
|
||||||
},
|
},
|
||||||
clone (event) {
|
clone (event) {
|
||||||
// console.log('clone',event );
|
|
||||||
const canvas = event.item.querySelector('canvas')
|
const canvas = event.item.querySelector('canvas')
|
||||||
// console.log('clone-canvas',canvas);
|
|
||||||
const canvasclone = event.clone.querySelector('canvas')
|
const canvasclone = event.clone.querySelector('canvas')
|
||||||
canvasclone.style.border = 'solid 1px yellow'
|
canvasclone.style.border = 'solid 1px yellow'
|
||||||
// console.log('clone-canvasclone',canvasclone);
|
|
||||||
if (canvas && canvasclone) {
|
if (canvas && canvasclone) {
|
||||||
const image = new Image()
|
const image = new Image()
|
||||||
image.src = canvas.toDataURL()
|
image.src = canvas.toDataURL()
|
||||||
// console.log('clone-image',image);
|
|
||||||
const ctxClone = canvasclone.getContext('2d')
|
const ctxClone = canvasclone.getContext('2d')
|
||||||
// ctxClone.drawImage(image,0,0);
|
|
||||||
image.onload = function () {
|
image.onload = function () {
|
||||||
ctxClone.drawImage(image, 0, 0)
|
ctxClone.drawImage(image, 0, 0)
|
||||||
}
|
}
|
||||||
@@ -662,7 +657,7 @@ export default {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (param.from == fromRoute.chartTemp) {
|
if (param.from == fromRoute.chartTemp) { // 模板列表
|
||||||
this.dataList = this.panelDataList
|
this.dataList = this.panelDataList
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.dataList.forEach((item, index) => {
|
this.dataList.forEach((item, index) => {
|
||||||
@@ -679,13 +674,12 @@ export default {
|
|||||||
}
|
}
|
||||||
if (!param.query) delete param.query
|
if (!param.query) delete param.query
|
||||||
// 根据panelId获得panel下的所有图表
|
// 根据panelId获得panel下的所有图表
|
||||||
this.$get('visual/panel/chart?panelId=' + params.panelId + '&pageSize=-1').then(response => {
|
this.$get('visual/panel/chart?panelId=' + params.panelId + '&groupId=0').then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
response.data.list.forEach((item, index) => {
|
response.data.list.forEach((item, index) => {
|
||||||
item.isLoaded = false
|
item.isLoaded = false
|
||||||
})
|
})
|
||||||
// response.data.list = response.data.list.filter((item) => item.groupId === -1 || !item.groupId) // 处理外层存在的groupItem
|
// response.data.list = response.data.list.filter((item) => item.groupId === -1 || !item.groupId) // 处理外层存在的groupItem
|
||||||
// console.log(response.data.list)
|
|
||||||
if (response.data.list) {
|
if (response.data.list) {
|
||||||
this.dataTotalListBak = response.data.list
|
this.dataTotalListBak = response.data.list
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
<div class="sub-list" style='position: relative;'>
|
<div class="sub-list" style='position: relative;'>
|
||||||
<!--el-drawer 打开后会对第一个未隐藏的元素聚焦 所以添加一隐藏的input 防止聚焦-->
|
<!--el-drawer 打开后会对第一个未隐藏的元素聚焦 所以添加一隐藏的input 防止聚焦-->
|
||||||
<input style='width: 0;height: 0;opacity: 0;display: inherit;' />
|
<input style='width: 0;height: 0;opacity: 0;display: inherit;' />
|
||||||
<el-menu @select="handleSelect" mode="horizontal" style='position: absolute;left:0px;top:0px;border-top: 1px solid #DCDFE6;'>
|
<el-menu @select="handleSelect" mode="horizontal" style='position: absolute;left:0px;top:0px;border-top: 1px solid #DCDFE6;' class="horizontal">
|
||||||
<el-submenu index="1" popper-class="fontSizeBox" style="width:40px;">
|
<el-submenu index="1" popper-class="horizontal" style="width:40px;">
|
||||||
<template slot="title" ><i class="nz-icon nz-icon-728bianjiqi_zitidaxiao" style="position: absolute;left: 10px;top: 4px;"></i></template>
|
<template slot="title" ><i class="nz-icon nz-icon-728bianjiqi_zitidaxiao" style="position: absolute;left: 10px;top: 4px;"></i></template>
|
||||||
<!--<el-submenu index="1-1">-->
|
<!--<el-submenu index="1-1">-->
|
||||||
<!--<template slot="title">文字大小</template>-->
|
<!--<template slot="title">文字大小</template>-->
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
<!--<el-menu-item index="1-2-2">Courier New</el-menu-item>-->
|
<!--<el-menu-item index="1-2-2">Courier New</el-menu-item>-->
|
||||||
<!--</el-submenu>-->
|
<!--</el-submenu>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
<!-- <el-submenu index="2" style="width:50px;">-->
|
<!-- <el-submenu index="2" style="width:50px;" popper-class="horizontal">-->
|
||||||
<!-- <template slot="title" ><i class="nz-icon nz-icon-upload console-title-icon" style="position: absolute;left: 10px;top: 4px;"></i></template>-->
|
<!-- <template slot="title" ><i class="nz-icon nz-icon-upload console-title-icon" style="position: absolute;left: 10px;top: 4px;"></i></template>-->
|
||||||
<!-- <el-menu-item @click="showUploadBox" index="2-1">-->
|
<!-- <el-menu-item @click="showUploadBox" index="2-1">-->
|
||||||
<!-- <div>{{$t('webshell.upload')}}</div>-->
|
<!-- <div>{{$t('webshell.upload')}}</div>-->
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
:popper-class="'popover-webshell'"
|
:popper-class="'popover-webshell'"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{{item.uuid.slice(0,7)}}
|
Session ID : {{item.uuid.slice(0,7).toLocaleUpperCase()}}
|
||||||
</div>
|
</div>
|
||||||
<span slot="reference"> <i class="nz-icon nz-icon-about" /></span>
|
<span slot="reference"> <i class="nz-icon nz-icon-about" /></span>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
@@ -978,4 +978,10 @@ export default {
|
|||||||
div.sp-header{
|
div.sp-header{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
/deep/ .horizontal .el-menu--horizontal>.el-submenu.is-active .el-submenu__title{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
/deep/ .horizontal .el-menu--popup .el-menu-item.is-active{
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<div :class="targetTab === 'panel' ? 'bottom-panel' : 'nz-table2'">
|
<div :class="targetTab === 'panel' ? 'bottom-panel' : 'nz-table2'">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="pagination-bottom">
|
<div class="pagination-bottom" v-if="showPagination">
|
||||||
<slot name="pagination"></slot>
|
<slot name="pagination"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,6 +76,10 @@ export default {
|
|||||||
customTool: {
|
customTool: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
showPagination: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -131,6 +135,7 @@ export default {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
|
overflow-y: auto;
|
||||||
&>div {
|
&>div {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
@@ -180,6 +185,7 @@ export default {
|
|||||||
.bottom-panel {
|
.bottom-panel {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
padding-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resize-modal {
|
.resize-modal {
|
||||||
|
|||||||
@@ -50,8 +50,8 @@
|
|||||||
import dataListMixin from '@/components/common/mixin/dataList'
|
import dataListMixin from '@/components/common/mixin/dataList'
|
||||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||||
import assetTable from "@/components/common/table/asset/assetTable";
|
import assetTable from '@/components/common/table/asset/assetTable'
|
||||||
import assetBox from "@/components/common/rightBox/asset/assetBox";
|
import assetBox from '@/components/common/rightBox/asset/assetBox'
|
||||||
export default {
|
export default {
|
||||||
name: 'assetTab',
|
name: 'assetTab',
|
||||||
mixins: [dataListMixin, subDataListMixin],
|
mixins: [dataListMixin, subDataListMixin],
|
||||||
@@ -184,16 +184,16 @@ export default {
|
|||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
watch:{
|
watch: {
|
||||||
obj:{
|
obj: {
|
||||||
immediate:true,
|
immediate: true,
|
||||||
deep:true,
|
deep: true,
|
||||||
handler(n,o){
|
handler (n, o) {
|
||||||
this.searchLabel.dcIds=n.id;
|
this.searchLabel.dcIds = n.id
|
||||||
this.getTableData();
|
this.getTableData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -204,6 +204,6 @@ export default {
|
|||||||
this.getDcData()
|
this.getDcData()
|
||||||
this.getSnmpCredentialData()
|
this.getSnmpCredentialData()
|
||||||
this.getFieldGroupData()
|
this.getFieldGroupData()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import deleteButton from '../../deleteButton'
|
|||||||
import dataListMixin from '@/components/common/mixin/dataList'
|
import dataListMixin from '@/components/common/mixin/dataList'
|
||||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||||
import cabinetTable from "@/components/common/table/settings/cabinetTable";
|
import cabinetTable from '@/components/common/table/settings/cabinetTable'
|
||||||
export default {
|
export default {
|
||||||
name: 'cabinetTab',
|
name: 'cabinetTab',
|
||||||
mixins: [dataListMixin, subDataListMixin],
|
mixins: [dataListMixin, subDataListMixin],
|
||||||
@@ -56,8 +56,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
url:'/cabinet',
|
url: '/cabinet',
|
||||||
tableId:'cabinetTable',
|
tableId: 'cabinetTable',
|
||||||
blankObject: {
|
blankObject: {
|
||||||
id: '',
|
id: '',
|
||||||
idcId: '',
|
idcId: '',
|
||||||
@@ -89,14 +89,14 @@ export default {
|
|||||||
disabled: false
|
disabled: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 切换tab
|
// 切换tab
|
||||||
changeTab (tab) {
|
changeTab (tab) {
|
||||||
this.$emit('changeTab', tab)
|
this.$emit('changeTab', tab)
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
obj: {
|
obj: {
|
||||||
|
|||||||
@@ -6,11 +6,17 @@
|
|||||||
:targetTab="targetTab"
|
:targetTab="targetTab"
|
||||||
@changeTab="changeTab"
|
@changeTab="changeTab"
|
||||||
class="full-width-height"
|
class="full-width-height"
|
||||||
|
:showPagination="false"
|
||||||
>
|
>
|
||||||
<template v-slot:title><span :title="obj.name">{{obj.name}}</span></template>
|
<template v-slot:title><span :title="obj.name">{{obj.name}}</span></template>
|
||||||
<template v-if="from === fromRoute.asset" v-slot:top-tool-right>
|
<template v-if="from === fromRoute.asset" v-slot:top-tool-right>
|
||||||
|
<div class="top-tool-search margin-r-20">
|
||||||
|
<el-input id="queryPanel" ref="queryPanel" v-model="filter.searchName" class="query-input-inactive" clearable size="small" @blur="blurInput" @clear="clearInput" @focus="focusInput">
|
||||||
|
<i slot="suffix" class="el-input__icon nz-icon nz-icon-search" style="float: right" @click="focusInput"></i>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
<pick-time ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false"></pick-time>
|
<pick-time ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false"></pick-time>
|
||||||
<export-excel
|
<!-- <export-excel
|
||||||
id="asset-list"
|
id="asset-list"
|
||||||
:params="searchLabel"
|
:params="searchLabel"
|
||||||
:permissions="{import: 'panel_chart_add', export: 'panel_view'}"
|
:permissions="{import: 'panel_chart_add', export: 'panel_view'}"
|
||||||
@@ -24,7 +30,21 @@
|
|||||||
<button id="asset-create-asset" v-has="'panel_chart_add'" :title="$t('overall.createAsset')" class="top-tool-btn" @click.stop="addChart">
|
<button id="asset-create-asset" v-has="'panel_chart_add'" :title="$t('overall.createAsset')" class="top-tool-btn" @click.stop="addChart">
|
||||||
<i class="nz-icon nz-icon-create-square"></i></button>
|
<i class="nz-icon nz-icon-create-square"></i></button>
|
||||||
</template>
|
</template>
|
||||||
</export-excel>
|
</export-excel>-->
|
||||||
|
<button id="asset-create-asset" v-has="'panel_chart_add'" :title="$t('overall.createAsset')" class="top-tool-btn margin-r-10" @click.stop="addChart">
|
||||||
|
<i class="nz-icon nz-icon-create-square"></i>
|
||||||
|
</button>
|
||||||
|
<top-tool-more-options
|
||||||
|
id="asset-list"
|
||||||
|
:params="searchLabel"
|
||||||
|
:permissions="{import: 'panel_chart_add', export: 'panel_view'}"
|
||||||
|
class="top-tool-export margin-r-10"
|
||||||
|
export-file-name="asset-charts"
|
||||||
|
export-url="visual/panel/export"
|
||||||
|
import-url="visual/panel/import"
|
||||||
|
@afterImport="getTableData"
|
||||||
|
>
|
||||||
|
</top-tool-more-options>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot>
|
<template v-slot>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
@@ -51,11 +71,10 @@
|
|||||||
import chartBox from '../../../page/dashboard/chartBox'
|
import chartBox from '../../../page/dashboard/chartBox'
|
||||||
import chartList from '../../../charts/chart-list'
|
import chartList from '../../../charts/chart-list'
|
||||||
import bus from '../../../../libs/bus'
|
import bus from '../../../../libs/bus'
|
||||||
import exportXLSX from '@/components/common/exportXLSX'
|
|
||||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||||
import { fromRoute } from '@/components/common/js/constants'
|
import { fromRoute } from '@/components/common/js/constants'
|
||||||
|
import topToolMoreOptions from '@/components/common/popBox/topToolMoreOptions'
|
||||||
export default {
|
export default {
|
||||||
name: 'panelTabNew',
|
name: 'panelTabNew',
|
||||||
mixins: [subDataListMixin],
|
mixins: [subDataListMixin],
|
||||||
@@ -139,7 +158,7 @@ export default {
|
|||||||
chartBox,
|
chartBox,
|
||||||
chartList,
|
chartList,
|
||||||
nzBottomDataList,
|
nzBottomDataList,
|
||||||
'export-excel': exportXLSX
|
topToolMoreOptions
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 刷新
|
// 刷新
|
||||||
@@ -256,14 +275,17 @@ export default {
|
|||||||
this.getData(this.filter)
|
this.getData(this.filter)
|
||||||
} else {
|
} else {
|
||||||
if (this.from == this.$CONSTANTS.fromRoute.chartTemp) {
|
if (this.from == this.$CONSTANTS.fromRoute.chartTemp) {
|
||||||
console.log(this.obj)
|
|
||||||
this.panelDataList = [this.obj]
|
|
||||||
console.log(this.panelData)
|
|
||||||
if (this.obj.type === 'group') {
|
if (this.obj.type === 'group') {
|
||||||
this.$get('/visual/panel/chart', { ids: this.obj.id,pageSize: -1 }).then(res => {
|
this.$get('/visual/panel/chart', { ids: this.obj.id,groupId:0}).then(res => {
|
||||||
console.log(res)
|
this.panelDataList = res.data.list
|
||||||
|
if (this.panelDataList.length > 0) {
|
||||||
|
this.showPanel.id = this.filter.panelId = 0
|
||||||
|
this.getData(this.filter)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
this.panelDataList = [this.obj]
|
||||||
if (this.panelDataList.length > 0) {
|
if (this.panelDataList.length > 0) {
|
||||||
this.showPanel.id = this.filter.panelId = 0
|
this.showPanel.id = this.filter.panelId = 0
|
||||||
this.getData(this.filter)
|
this.getData(this.filter)
|
||||||
@@ -333,7 +355,7 @@ export default {
|
|||||||
this.pageObj.pageSize = val
|
this.pageObj.pageSize = val
|
||||||
this.getTableData(this.obj.id)
|
this.getTableData(this.obj.id)
|
||||||
},
|
},
|
||||||
search: function () {
|
search () {
|
||||||
if (this.$refs.chartList) {
|
if (this.$refs.chartList) {
|
||||||
this.$refs.chartList.searchCharts(this.filter.searchName)
|
this.$refs.chartList.searchCharts(this.filter.searchName)
|
||||||
}
|
}
|
||||||
@@ -346,13 +368,13 @@ export default {
|
|||||||
_self.$refs.chartList.loadChartData(_self.scrollbarWrap.scrollTop)
|
_self.$refs.chartList.loadChartData(_self.scrollbarWrap.scrollTop)
|
||||||
}, 300))
|
}, 300))
|
||||||
},
|
},
|
||||||
focusInput: function () {
|
focusInput () {
|
||||||
let classVal = document.getElementById('queryPanel').parentElement.getAttribute('class')
|
let classVal = document.getElementById('queryPanel').parentElement.getAttribute('class')
|
||||||
classVal = classVal.replace('query-input-inactive', 'query-input-active')
|
classVal = classVal.replace('query-input-inactive', 'query-input-active')
|
||||||
document.getElementById('queryPanel').parentElement.setAttribute('class', classVal)
|
document.getElementById('queryPanel').parentElement.setAttribute('class', classVal)
|
||||||
this.$refs.queryPanel.focus()
|
this.$refs.queryPanel.focus()
|
||||||
},
|
},
|
||||||
blurInput: function () {
|
blurInput () {
|
||||||
if (!this.filter.searchName || this.filter.searchName == '') {
|
if (!this.filter.searchName || this.filter.searchName == '') {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
let classVal = document.getElementById('queryPanel').parentElement.getAttribute('class')
|
let classVal = document.getElementById('queryPanel').parentElement.getAttribute('class')
|
||||||
@@ -361,10 +383,10 @@ export default {
|
|||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearInput: function () {
|
clearInput () {
|
||||||
this.$refs.queryPanel.focus()
|
this.$refs.queryPanel.focus()
|
||||||
},
|
},
|
||||||
syncChart: function () {
|
syncChart () {
|
||||||
if (this.from == this.fromRoute.asset || this.from == this.fromRoute.model) {
|
if (this.from == this.fromRoute.asset || this.from == this.fromRoute.model) {
|
||||||
this.$confirm(this.$t('tip.syncTip'), {
|
this.$confirm(this.$t('tip.syncTip'), {
|
||||||
confirmButtonText: this.$t('tip.yes'),
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
@@ -408,14 +430,14 @@ export default {
|
|||||||
this.tableHover = false
|
this.tableHover = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted () {
|
||||||
this.scrollbarWrap = this.$refs.dashboardScrollbar
|
this.scrollbarWrap = this.$refs.dashboardScrollbar
|
||||||
this.onScroll()
|
this.onScroll()
|
||||||
document.querySelector('#tableList').addEventListener('mouseenter', this.tableListEnter)
|
document.querySelector('#tableList').addEventListener('mouseenter', this.tableListEnter)
|
||||||
document.querySelector('#tableList').addEventListener('mouseleave', this.tableListLeave)
|
document.querySelector('#tableList').addEventListener('mouseleave', this.tableListLeave)
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'filter.searchName': function (n, o) {
|
'filter.searchName' (n, o) {
|
||||||
const temp = this
|
const temp = this
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
temp.search()
|
temp.search()
|
||||||
@@ -651,12 +673,6 @@ export default {
|
|||||||
.nz-dashboard-dropdown {
|
.nz-dashboard-dropdown {
|
||||||
z-index: 3001 !important;
|
z-index: 3001 !important;
|
||||||
}
|
}
|
||||||
.panel .top-tools input {
|
|
||||||
background-color: $content-right-background-color;
|
|
||||||
}
|
|
||||||
.panel .top-tools .el-input__inner {
|
|
||||||
background-color: $content-right-background-color;
|
|
||||||
}
|
|
||||||
.panel-calendar .el-range-editor--mini.el-input__inner {
|
.panel-calendar .el-range-editor--mini.el-input__inner {
|
||||||
height: 25px !important;
|
height: 25px !important;
|
||||||
border-color: #d8d8d8;
|
border-color: #d8d8d8;
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
<div style="height: 1px; width: 100%; background-color: #cccccc;"></div>
|
<div style="height: 1px; width: 100%; background-color: #cccccc;"></div>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item index="101-3">
|
<el-menu-item index="101-3">
|
||||||
<div @click="showPwdDialog" id="header-to-changepwd">{{$t('overall.changePwd')}}</div>
|
<div @click="showPinDialog" id="header-to-changepin">{{$t('overall.changePin')}}</div>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item index="101-4">
|
<el-menu-item index="101-4">
|
||||||
<div @click="logout" id="header-to-logout">{{$t('overall.signOut')}}</div>
|
<div @click="logout" id="header-to-logout">{{$t('overall.signOut')}}</div>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<transition name="right-box">
|
<transition name="right-box">
|
||||||
<dc-box @close="closeDcBox" :dc="dc" :user-data="userData" @reload="getAssetData" v-if="rightBox.dc.show"></dc-box>
|
<dc-box @close="closeDcBox" :dc="dc" :user-data="userData" @reload="getAssetData" v-if="rightBox.dc.show"></dc-box>
|
||||||
</transition>
|
</transition>
|
||||||
<change-password :cur-user="username" :show-dialog="showChangePwd" @click="showPwdDialog" @dialogClosed="dialogClosed"></change-password>
|
<change-password :cur-user="username" :show-dialog="showChangePin" @click="showPinDialog" @dialogClosed="dialogClosed"></change-password>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -162,11 +162,11 @@
|
|||||||
import bus from '../../libs/bus'
|
import bus from '../../libs/bus'
|
||||||
import dcBox from './rightBox/dcBox' // dc弹框
|
import dcBox from './rightBox/dcBox' // dc弹框
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex'
|
||||||
import changePwd from '../page/config/changePwd'
|
import changePin from '../page/config/changePin'
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
components: {
|
components: {
|
||||||
'change-password': changePwd,
|
'change-password': changePin,
|
||||||
'dc-box': dcBox
|
'dc-box': dcBox
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -283,7 +283,7 @@ export default {
|
|||||||
permission: 'header_add_rule'
|
permission: 'header_add_rule'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
showChangePwd: false
|
showChangePin: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -338,10 +338,10 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
username: '',
|
username: '',
|
||||||
security_level: 'noAuthNoPriv', // noAuthNoPriv/authNoPriv/authPriv
|
security_level: 'noAuthNoPriv', // noAuthNoPriv/authNoPriv/authPriv
|
||||||
password: '',
|
pinrd: '',
|
||||||
auth_protocol: 'MD5', // MD5/SHA
|
auth_protocol: 'MD5', // MD5/SHA
|
||||||
priv_protocol: 'DES', // DES/AES
|
priv_protocol: 'DES', // DES/AES
|
||||||
priv_password: '',
|
priv_pin: '',
|
||||||
context_name: ''
|
context_name: ''
|
||||||
}
|
}
|
||||||
} else if (item.type == 3) {
|
} else if (item.type == 3) {
|
||||||
@@ -483,11 +483,11 @@ export default {
|
|||||||
window.location.reload()
|
window.location.reload()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
showPwdDialog () {
|
showPinDialog () {
|
||||||
this.showChangePwd = true
|
this.showChangePin = true
|
||||||
},
|
},
|
||||||
dialogClosed () {
|
dialogClosed () {
|
||||||
this.showChangePwd = false
|
this.showChangePin = false
|
||||||
},
|
},
|
||||||
cancel () {
|
cancel () {
|
||||||
this.jumpTo(this.$route.path.slice(1, this.$route.path.length))
|
this.jumpTo(this.$route.path.slice(1, this.$route.path.length))
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{'height': height + 'px'}" class="search-box__container">
|
<div :style="{'height': height + 'px'}" class="search-box__container">
|
||||||
<div v-for="(data, type, index) in titleSearchListCopy" v-if="data.show" :key="index" ref="searchContentBox" class="search-content-box">
|
<div v-for="(data, type, index) in titleSearchListCopy" v-cloak v-if="data.show" :key="index" ref="searchContentBox" class="search-content-box">
|
||||||
<label class="search-title">{{data.label}}:</label>
|
<label class="search-title">{{data.label}}:</label>
|
||||||
<el-checkbox-group v-if="data.type === 'checkBox'" ref="searchContent" v-model="selectValueOut[data.key]">
|
<el-checkbox-group v-if="data.type === 'checkBox'" ref="searchContent" v-model="selectValueOut[data.key]">
|
||||||
<template v-for="(item, j) in data.children">
|
<template v-for="(item, j) in data.children">
|
||||||
<el-checkbox v-show="!data.showMore || j < data.index" :key="j" :label="item.value">{{item.key || item.name || item.label}}</el-checkbox>
|
<el-checkbox v-if="!data.showMore || j < data.index" :key="j" :label="item.value">{{item.key || item.name || item.label}}</el-checkbox>
|
||||||
</template>
|
</template>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<dropdown
|
<template v-for="(item, j) in data.children" v-else-if="data.type === 'dropdownCheckBox'">
|
||||||
v-for="(item, j) in data.children"
|
<dropdown
|
||||||
v-else-if="data.type === 'dropdownCheckBox'"
|
v-if="!data.showMore || j < data.index"
|
||||||
:key="j"
|
:key="j"
|
||||||
:ref="`${type}_cascader`"
|
:ref="`${type}_cascader`"
|
||||||
:collapse-tags="true"
|
:collapse-tags="true"
|
||||||
:item="item"
|
:item="item"
|
||||||
@blur="casFocus"
|
@blur="casFocus"
|
||||||
@change="casChange(type, data.key)"
|
@change="casChange(type, data.key)"
|
||||||
@focus="casFocus"
|
@focus="casFocus"
|
||||||
></dropdown>
|
></dropdown>
|
||||||
|
</template>
|
||||||
<span v-show="contentWidth <= data.width" class="search-more" @click="changShowMore(type)">更多 <i :class="data.showMore?'el-icon-arrow-down':'el-icon-arrow-up'"/></span>
|
<span v-show="contentWidth <= data.width" class="search-more" @click="changShowMore(type)">更多 <i :class="data.showMore?'el-icon-arrow-down':'el-icon-arrow-up'"/></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,6 +101,7 @@ export default {
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
handler (n) {
|
handler (n) {
|
||||||
|
console.log(n)
|
||||||
this.$emit('reload', n)
|
this.$emit('reload', n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const cn = {
|
|||||||
active: '活跃',
|
active: '活跃',
|
||||||
type: '类别',
|
type: '类别',
|
||||||
detail: '详细信息',
|
detail: '详细信息',
|
||||||
changePwd: '修改密码',
|
changePin: '修改密码',
|
||||||
createCabinet: '创建机柜',
|
createCabinet: '创建机柜',
|
||||||
createModel: '创建型号',
|
createModel: '创建型号',
|
||||||
createModule: '创建模块',
|
createModule: '创建模块',
|
||||||
@@ -145,8 +145,8 @@ const cn = {
|
|||||||
finish: '完成',
|
finish: '完成',
|
||||||
invalidDb: '数据库配置可能存在一些错误',
|
invalidDb: '数据库配置可能存在一些错误',
|
||||||
invalidRedis: 'Redis的配置可能有一些错误',
|
invalidRedis: 'Redis的配置可能有一些错误',
|
||||||
invalidpin: 'Redis的密码可能错误',
|
invalidPin: 'Redis的密码可能错误',
|
||||||
requirepin: 'Redis可能需要密码',
|
requirePin: 'Redis可能需要密码',
|
||||||
wait: '配置已保存,请耐心等待生效',
|
wait: '配置已保存,请耐心等待生效',
|
||||||
reloadTimeout: '重新启动服务器花了太多时间,安装可能有一些问题',
|
reloadTimeout: '重新启动服务器花了太多时间,安装可能有一些问题',
|
||||||
hadConfig: '已经有人开始配置系统',
|
hadConfig: '已经有人开始配置系统',
|
||||||
@@ -538,8 +538,8 @@ const cn = {
|
|||||||
userTip: '用户名提示',
|
userTip: '用户名提示',
|
||||||
pinTip: '密码提示',
|
pinTip: '密码提示',
|
||||||
reloginpinTip: 'RELOGIN提示',
|
reloginpinTip: 'RELOGIN提示',
|
||||||
userPwdIntroduce: '请指定用户名和密码提示以便TELNET登录过程可自动运行',
|
userPinIntroduce: '请指定用户名和密码提示以便TELNET登录过程可自动运行',
|
||||||
reLoginPwdIntroduce: '请指定密码提示以便RELOGIN登录过程可自动运行',
|
reLoginPinIntroduce: '请指定密码提示以便RELOGIN登录过程可自动运行',
|
||||||
username: '用户名',
|
username: '用户名',
|
||||||
port: '端口',
|
port: '端口',
|
||||||
upload: '上传',
|
upload: '上传',
|
||||||
@@ -616,15 +616,15 @@ const cn = {
|
|||||||
editUser: '编辑用户',
|
editUser: '编辑用户',
|
||||||
notCurrentlySupport: '暂不支持',
|
notCurrentlySupport: '暂不支持',
|
||||||
pin: '密码',
|
pin: '密码',
|
||||||
oldPwd: '旧密码',
|
oldPin: '旧密码',
|
||||||
inputOldPwd: '请输入旧密码',
|
inputOldPin: '请输入旧密码',
|
||||||
newPwd: '新密码',
|
newPin: '新密码',
|
||||||
inputNewPwd: '请输入新密码',
|
inputNewPin: '请输入新密码',
|
||||||
confirmPwd: '确认密码',
|
confirmPin: '确认密码',
|
||||||
inputConfirmPwd: '请再次输入密码',
|
inputConfirmPin: '请再次输入密码',
|
||||||
invalidPwd: '无效的密码,最少6个字符',
|
invalidPin: '无效的密码,最少6个字符',
|
||||||
confirmPwdErr: '两次密码输入不一致',
|
confirmPinErr: '两次密码输入不一致',
|
||||||
reinputPwd: '请再次输入密码',
|
reinputPin: '请再次输入密码',
|
||||||
notification: '通知',
|
notification: '通知',
|
||||||
mobile: '电话'
|
mobile: '电话'
|
||||||
},
|
},
|
||||||
@@ -866,14 +866,14 @@ const cn = {
|
|||||||
smtpHost: 'SMTP主机',
|
smtpHost: 'SMTP主机',
|
||||||
smtpPort: 'SMTP端口',
|
smtpPort: 'SMTP端口',
|
||||||
smtpAccount: 'SMTP账号',
|
smtpAccount: 'SMTP账号',
|
||||||
smtpPwd: 'SMTP密码',
|
smtpPin: 'SMTP密码',
|
||||||
sendAccount: '发送账号',
|
sendAccount: '发送账号',
|
||||||
timeout: '超时时间',
|
timeout: '超时时间',
|
||||||
testAccount: '测试账号',
|
testAccount: '测试账号',
|
||||||
useSSL: 'SSL',
|
useSSL: 'SSL',
|
||||||
useTLS: 'TLS',
|
useTLS: 'TLS',
|
||||||
testConnection: '测试连接',
|
testConnection: '测试连接',
|
||||||
pwdTip: '提示:一些邮件提供商需要输入的是Token',
|
pinTip: '提示:一些邮件提供商需要输入的是Token',
|
||||||
sendAccountTip: '提示:发送邮件账号,默认使用SMTP账号作为发送账号',
|
sendAccountTip: '提示:发送邮件账号,默认使用SMTP账号作为发送账号',
|
||||||
testAccountTip: '提示:仅用来作为测试邮件收件人',
|
testAccountTip: '提示:仅用来作为测试邮件收件人',
|
||||||
sslTip: '如果SMTP端口是465,通常需要启用SSL',
|
sslTip: '如果SMTP端口是465,通常需要启用SSL',
|
||||||
@@ -892,7 +892,7 @@ const cn = {
|
|||||||
ldap: 'LDAP',
|
ldap: 'LDAP',
|
||||||
address: 'LDAP地址',
|
address: 'LDAP地址',
|
||||||
dn: 'Bind DN',
|
dn: 'Bind DN',
|
||||||
pwd: '密码',
|
pin: '密码',
|
||||||
ou: '用户OU',
|
ou: '用户OU',
|
||||||
ouTip: '使用符号 "|" 分隔OU',
|
ouTip: '使用符号 "|" 分隔OU',
|
||||||
filter: '用户过滤器',
|
filter: '用户过滤器',
|
||||||
@@ -932,11 +932,11 @@ const cn = {
|
|||||||
reset: {
|
reset: {
|
||||||
reset: '重置',
|
reset: '重置',
|
||||||
type: '类型',
|
type: '类型',
|
||||||
pwd: '密码',
|
pin: '密码',
|
||||||
metric: '指标',
|
metric: '指标',
|
||||||
alert: '告警',
|
alert: '告警',
|
||||||
sysConfig: '系统设置',
|
sysConfig: '系统设置',
|
||||||
pwdTip: '请输入密码',
|
pinTip: '请输入密码',
|
||||||
promptTitle: '确认密码',
|
promptTitle: '确认密码',
|
||||||
yes: '是',
|
yes: '是',
|
||||||
no: '否'
|
no: '否'
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const en = {
|
|||||||
back: 'Back', // 返回
|
back: 'Back', // 返回
|
||||||
unavailable: 'Unavailable',
|
unavailable: 'Unavailable',
|
||||||
available: 'Available',
|
available: 'Available',
|
||||||
changePwd: 'Change password', // 修改密码
|
changePin: 'Change password', // 修改密码
|
||||||
createChart: 'Create chart',
|
createChart: 'Create chart',
|
||||||
createProject: 'Create project',
|
createProject: 'Create project',
|
||||||
createEndpoint: 'Create endpoint',
|
createEndpoint: 'Create endpoint',
|
||||||
@@ -153,8 +153,8 @@ const en = {
|
|||||||
finish: 'Finish',
|
finish: 'Finish',
|
||||||
invalidDb: 'There may be some errors in the configuration of the database',
|
invalidDb: 'There may be some errors in the configuration of the database',
|
||||||
invalidRedis: 'There may be some errors in the configuration of the Redis',
|
invalidRedis: 'There may be some errors in the configuration of the Redis',
|
||||||
invalidpin: "Redis's password may be wrong",
|
invalidPin: "Redis's password may be wrong",
|
||||||
requirepin: 'The password may be required by the Redis',
|
requirePin: 'The password may be required by the Redis',
|
||||||
wait: 'The configuration has been saved, please wait patiently for it to take effect',
|
wait: 'The configuration has been saved, please wait patiently for it to take effect',
|
||||||
reloadTimeout: 'It took too much time to restart the server, there may be some problems when you install',
|
reloadTimeout: 'It took too much time to restart the server, there may be some problems when you install',
|
||||||
hadConfig: 'Someone has started to configure the system',
|
hadConfig: 'Someone has started to configure the system',
|
||||||
@@ -182,7 +182,7 @@ const en = {
|
|||||||
authPin: 'Password',
|
authPin: 'Password',
|
||||||
authUserTip: 'Username prompt',
|
authUserTip: 'Username prompt',
|
||||||
authPinTip: 'Password prompt',
|
authPinTip: 'Password prompt',
|
||||||
authPriKey: 'Key',
|
authPriKey: 'Key'
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
username: 'Username',
|
username: 'Username',
|
||||||
@@ -542,9 +542,9 @@ const en = {
|
|||||||
telnetProtocol: 'Telnet',
|
telnetProtocol: 'Telnet',
|
||||||
userTip: 'User tip', // 用户名提示
|
userTip: 'User tip', // 用户名提示
|
||||||
pinTip: 'Password tip', // 密码提示
|
pinTip: 'Password tip', // 密码提示
|
||||||
reloginpinTip: 'Relogin tip', // 密码提示
|
reloginPinTip: 'Relogin tip', // 密码提示
|
||||||
userPwdIntroduce: 'Please specify a user name and password so that the telenet login process can automatically log in',
|
userPinIntroduce: 'Please specify a user name and password so that the telenet login process can automatically log in',
|
||||||
reLoginPwdIntroduce: 'Please specify the password prompt so that the login process can run automatically',
|
reLoginPinIntroduce: 'Please specify the password prompt so that the login process can run automatically',
|
||||||
username: 'Username', // '用户名'
|
username: 'Username', // '用户名'
|
||||||
port: 'Port', // '端口'
|
port: 'Port', // '端口'
|
||||||
upload: 'Upload', // '上传'
|
upload: 'Upload', // '上传'
|
||||||
@@ -600,7 +600,7 @@ const en = {
|
|||||||
option: 'Operation', // "操作"
|
option: 'Operation', // "操作"
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
dc: 'DataCenter',
|
dc: 'DataCenter',
|
||||||
type: 'Types',
|
type: 'Types'
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
config: 'Settings', // "设置"
|
config: 'Settings', // "设置"
|
||||||
@@ -625,15 +625,15 @@ const en = {
|
|||||||
editUser: 'Edit user', // "编辑用户"
|
editUser: 'Edit user', // "编辑用户"
|
||||||
notCurrentlySupport: 'Not available', // '暂不支持'
|
notCurrentlySupport: 'Not available', // '暂不支持'
|
||||||
pin: 'Password', // '密码'
|
pin: 'Password', // '密码'
|
||||||
oldPwd: 'Old password',
|
oldPin: 'Old password',
|
||||||
inputOldPwd: 'Please input old password',
|
inputOldPin: 'Please input old password',
|
||||||
newPwd: 'New password',
|
newPin: 'New password',
|
||||||
inputNewPwd: 'Please input new password',
|
inputNewPin: 'Please input new password',
|
||||||
confirmPwd: 'Confirm password',
|
confirmPin: 'Confirm password',
|
||||||
inputConfirmPwd: 'Please input confirm password',
|
inputConfirmPin: 'Please input confirm password',
|
||||||
invalidPwd: 'invalide password,the length at least 6',
|
invalidPin: 'invalide password,the length at least 6',
|
||||||
confirmPwdErr: 'The two passwords are inconsistent',
|
confirmPinErr: 'The two passwords are inconsistent',
|
||||||
reinputPwd: 'Enter password again',
|
reinputPin: 'Enter password again',
|
||||||
notification: 'Notification',
|
notification: 'Notification',
|
||||||
mobile: 'Mobile'
|
mobile: 'Mobile'
|
||||||
},
|
},
|
||||||
@@ -883,14 +883,14 @@ const en = {
|
|||||||
smtpHost: 'SMTP host',
|
smtpHost: 'SMTP host',
|
||||||
smtpPort: 'SMTP port',
|
smtpPort: 'SMTP port',
|
||||||
smtpAccount: 'SMTP account',
|
smtpAccount: 'SMTP account',
|
||||||
smtpPwd: 'SMTP password',
|
smtpPin: 'SMTP password',
|
||||||
sendAccount: 'Send account',
|
sendAccount: 'Send account',
|
||||||
timeout: 'Timeout',
|
timeout: 'Timeout',
|
||||||
testAccount: 'Test account',
|
testAccount: 'Test account',
|
||||||
useSSL: 'SSL',
|
useSSL: 'SSL',
|
||||||
useTLS: 'TLS',
|
useTLS: 'TLS',
|
||||||
testConnection: 'Test connection',
|
testConnection: 'Test connection',
|
||||||
pwdTip: 'Tip:Some email providers need to enter token',
|
pinTip: 'Tip:Some email providers need to enter token',
|
||||||
sendAccountTip: 'Tip:The SMTP account is used as the sending account by default',
|
sendAccountTip: 'Tip:The SMTP account is used as the sending account by default',
|
||||||
testAccountTip: 'Tip:Used only as test mail recipient',
|
testAccountTip: 'Tip:Used only as test mail recipient',
|
||||||
sslTip: 'If the SMTP port is 465, you usually need to enable SSL',
|
sslTip: 'If the SMTP port is 465, you usually need to enable SSL',
|
||||||
@@ -909,7 +909,7 @@ const en = {
|
|||||||
ldap: 'LDAP',
|
ldap: 'LDAP',
|
||||||
address: 'LDAP address',
|
address: 'LDAP address',
|
||||||
dn: 'Bind DN',
|
dn: 'Bind DN',
|
||||||
pwd: 'Password',
|
pin: 'Password',
|
||||||
ou: 'User OU',
|
ou: 'User OU',
|
||||||
ouTip: 'Use the "|" symbol to separate OU',
|
ouTip: 'Use the "|" symbol to separate OU',
|
||||||
filter: 'User filter',
|
filter: 'User filter',
|
||||||
@@ -952,11 +952,11 @@ const en = {
|
|||||||
reset: {
|
reset: {
|
||||||
reset: 'Reset',
|
reset: 'Reset',
|
||||||
type: 'Type',
|
type: 'Type',
|
||||||
pwd: 'Password',
|
pin: 'Password',
|
||||||
metric: 'Metric',
|
metric: 'Metric',
|
||||||
alert: 'Alert',
|
alert: 'Alert',
|
||||||
sysConfig: 'System config',
|
sysConfig: 'System config',
|
||||||
pwdTip: 'Please input your password',
|
pinTip: 'Please input your password',
|
||||||
promptTitle: 'Confirm',
|
promptTitle: 'Confirm',
|
||||||
yes: 'Yes',
|
yes: 'Yes',
|
||||||
no: 'No'
|
no: 'No'
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ export default {
|
|||||||
// 登录成功,记录用户名、token和lang
|
// 登录成功,记录用户名、token和lang
|
||||||
sessionStorage.setItem('nz-username', this.loginData.username)
|
sessionStorage.setItem('nz-username', this.loginData.username)
|
||||||
localStorage.setItem('nz-username', this.loginData.username)
|
localStorage.setItem('nz-username', this.loginData.username)
|
||||||
|
localStorage.setItem('nz-prometheus-federation-enabled', res.data.prometheusFederationEnabled)
|
||||||
localStorage.setItem('nz-language', this.lang)
|
localStorage.setItem('nz-language', this.lang)
|
||||||
this.$i18n.locale = this.lang
|
this.$i18n.locale = this.lang
|
||||||
this.loginSuccess(res)
|
this.loginSuccess(res)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import DatePicker from './src/picker/date-picker'
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
DatePicker.install = function install (Vue) {
|
||||||
|
Vue.component(DatePicker.name, DatePicker)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DatePicker
|
||||||
@@ -0,0 +1,441 @@
|
|||||||
|
<template>
|
||||||
|
<table
|
||||||
|
cellspacing="0"
|
||||||
|
cellpadding="0"
|
||||||
|
class="el-date-table"
|
||||||
|
@click="handleClick"
|
||||||
|
@mousemove="handleMouseMove"
|
||||||
|
:class="{ 'is-week-mode': selectionMode === 'week' }">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th v-if="showWeekNumber">{{ t('el.datepicker.week') }}</th>
|
||||||
|
<th v-for="(week, key) in WEEKS" :key="key">{{ t('el.datepicker.weeks.' + week) }}</th>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
class="el-date-table__row"
|
||||||
|
v-for="(row, key) in rows"
|
||||||
|
:class="{ current: isWeekActive(row[1]) }"
|
||||||
|
:key="key">
|
||||||
|
<td
|
||||||
|
v-for="(cell, key) in row"
|
||||||
|
:class="getCellClasses(cell)"
|
||||||
|
:key="key">
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{{ cell.text }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, prevDate, nextDate, isDate, clearTime as _clearTime } from 'element-ui/src/utils/date-util'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import { arrayFindIndex, arrayFind, coerceTruthyValueToArray } from 'element-ui/src/utils/util'
|
||||||
|
|
||||||
|
const WEEKS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
|
||||||
|
const getDateTimestamp = function (time) {
|
||||||
|
if (typeof time === 'number' || typeof time === 'string') {
|
||||||
|
return _clearTime(new Date(time)).getTime()
|
||||||
|
} else if (time instanceof Date) {
|
||||||
|
return _clearTime(time).getTime()
|
||||||
|
} else {
|
||||||
|
return NaN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the first element that satisfies `pred` from arr
|
||||||
|
// return a new array if modification occurs
|
||||||
|
// return the original array otherwise
|
||||||
|
const removeFromArray = function (arr, pred) {
|
||||||
|
const idx = typeof pred === 'function' ? arrayFindIndex(arr, pred) : arr.indexOf(pred)
|
||||||
|
return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
firstDayOfWeek: {
|
||||||
|
default: 7,
|
||||||
|
type: Number,
|
||||||
|
validator: val => val >= 1 && val <= 7
|
||||||
|
},
|
||||||
|
|
||||||
|
value: {},
|
||||||
|
|
||||||
|
defaultValue: {
|
||||||
|
validator (val) {
|
||||||
|
// either: null, valid Date object, Array of valid Date objects
|
||||||
|
return val === null || isDate(val) || (Array.isArray(val) && val.every(isDate))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
date: {},
|
||||||
|
|
||||||
|
selectionMode: {
|
||||||
|
default: 'day'
|
||||||
|
},
|
||||||
|
|
||||||
|
showWeekNumber: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
disabledDate: {},
|
||||||
|
|
||||||
|
cellClassName: {},
|
||||||
|
|
||||||
|
minDate: {},
|
||||||
|
|
||||||
|
maxDate: {},
|
||||||
|
|
||||||
|
rangeState: {
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
endDate: null,
|
||||||
|
selecting: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
offsetDay () {
|
||||||
|
const week = this.firstDayOfWeek
|
||||||
|
// 周日为界限,左右偏移的天数,3217654 例如周一就是 -1,目的是调整前两行日期的位置
|
||||||
|
return week > 3 ? 7 - week : -week
|
||||||
|
},
|
||||||
|
|
||||||
|
WEEKS () {
|
||||||
|
const week = this.firstDayOfWeek
|
||||||
|
return WEEKS.concat(WEEKS).slice(week, week + 7)
|
||||||
|
},
|
||||||
|
|
||||||
|
year () {
|
||||||
|
return this.date.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
month () {
|
||||||
|
return this.date.getMonth()
|
||||||
|
},
|
||||||
|
|
||||||
|
startDate () {
|
||||||
|
return getStartDateOfMonth(this.year, this.month)
|
||||||
|
},
|
||||||
|
|
||||||
|
rows () {
|
||||||
|
// TODO: refactory rows / getCellClasses
|
||||||
|
const date = new Date(this.year, this.month, 1)
|
||||||
|
let day = getFirstDayOfMonth(date) // day of first day
|
||||||
|
const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth())
|
||||||
|
const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), (date.getMonth() === 0 ? 11 : date.getMonth() - 1))
|
||||||
|
|
||||||
|
day = (day === 0 ? 7 : day)
|
||||||
|
|
||||||
|
const offset = this.offsetDay
|
||||||
|
const rows = this.tableRows
|
||||||
|
let count = 1
|
||||||
|
|
||||||
|
const startDate = this.startDate
|
||||||
|
const disabledDate = this.disabledDate
|
||||||
|
const cellClassName = this.cellClassName
|
||||||
|
const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : []
|
||||||
|
const now = getDateTimestamp(new Date())
|
||||||
|
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
const row = rows[i]
|
||||||
|
|
||||||
|
if (this.showWeekNumber) {
|
||||||
|
if (!row[0]) {
|
||||||
|
row[0] = { type: 'week', text: getWeekNumber(nextDate(startDate, i * 7 + 1)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < 7; j++) {
|
||||||
|
let cell = row[this.showWeekNumber ? j + 1 : j]
|
||||||
|
if (!cell) {
|
||||||
|
cell = { row: i, column: j, type: 'normal', inRange: false, start: false, end: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.type = 'normal'
|
||||||
|
|
||||||
|
const index = i * 7 + j
|
||||||
|
const time = nextDate(startDate, index - offset).getTime()
|
||||||
|
cell.inRange = time >= getDateTimestamp(this.minDate) && time <= getDateTimestamp(this.maxDate)
|
||||||
|
cell.start = this.minDate && time === getDateTimestamp(this.minDate)
|
||||||
|
cell.end = this.maxDate && time === getDateTimestamp(this.maxDate)
|
||||||
|
const isToday = time === now
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
cell.type = 'today'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= 0 && i <= 1) {
|
||||||
|
const numberOfDaysFromPreviousMonth = day + offset < 0 ? 7 + day + offset : day + offset
|
||||||
|
|
||||||
|
if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
|
||||||
|
cell.text = count++
|
||||||
|
} else {
|
||||||
|
cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - j % 7) + 1 + i * 7
|
||||||
|
cell.type = 'prev-month'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (count <= dateCountOfMonth) {
|
||||||
|
cell.text = count++
|
||||||
|
} else {
|
||||||
|
cell.text = count++ - dateCountOfMonth
|
||||||
|
cell.type = 'next-month'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cellDate = new Date(time)
|
||||||
|
cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate)
|
||||||
|
cell.selected = arrayFind(selectedDate, date => date.getTime() === cellDate.getTime())
|
||||||
|
cell.customClass = typeof cellClassName === 'function' && cellClassName(cellDate)
|
||||||
|
this.$set(row, this.showWeekNumber ? j + 1 : j, cell)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.selectionMode === 'week') {
|
||||||
|
const start = this.showWeekNumber ? 1 : 0
|
||||||
|
const end = this.showWeekNumber ? 7 : 6
|
||||||
|
const isWeekActive = this.isWeekActive(row[start + 1])
|
||||||
|
|
||||||
|
row[start].inRange = isWeekActive
|
||||||
|
row[start].start = isWeekActive
|
||||||
|
row[end].inRange = isWeekActive
|
||||||
|
row[end].end = isWeekActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'rangeState.endDate' (newVal) {
|
||||||
|
this.markRange(this.minDate, newVal)
|
||||||
|
},
|
||||||
|
|
||||||
|
minDate (newVal, oldVal) {
|
||||||
|
if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
|
||||||
|
this.markRange(this.minDate, this.maxDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maxDate (newVal, oldVal) {
|
||||||
|
if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
|
||||||
|
this.markRange(this.minDate, this.maxDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
tableRows: [[], [], [], [], [], []],
|
||||||
|
lastRow: null,
|
||||||
|
lastColumn: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
cellMatchesDate (cell, date) {
|
||||||
|
const value = new Date(date)
|
||||||
|
return this.year === value.getFullYear() &&
|
||||||
|
this.month === value.getMonth() &&
|
||||||
|
Number(cell.text) === value.getDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
getCellClasses (cell) {
|
||||||
|
const selectionMode = this.selectionMode
|
||||||
|
const defaultValue = this.defaultValue ? Array.isArray(this.defaultValue) ? this.defaultValue : [this.defaultValue] : []
|
||||||
|
|
||||||
|
const classes = []
|
||||||
|
if ((cell.type === 'normal' || cell.type === 'today') && !cell.disabled) {
|
||||||
|
classes.push('available')
|
||||||
|
if (cell.type === 'today') {
|
||||||
|
classes.push('today')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
classes.push(cell.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.type === 'normal' && defaultValue.some(date => this.cellMatchesDate(cell, date))) {
|
||||||
|
classes.push('default')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectionMode === 'day' && (cell.type === 'normal' || cell.type === 'today') && this.cellMatchesDate(cell, this.value)) {
|
||||||
|
classes.push('current')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.inRange && ((cell.type === 'normal' || cell.type === 'today') || this.selectionMode === 'week')) {
|
||||||
|
classes.push('in-range')
|
||||||
|
|
||||||
|
if (cell.start) {
|
||||||
|
classes.push('start-date')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.end) {
|
||||||
|
classes.push('end-date')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.disabled) {
|
||||||
|
classes.push('disabled')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.selected) {
|
||||||
|
classes.push('selected')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.customClass) {
|
||||||
|
classes.push(cell.customClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes.join(' ')
|
||||||
|
},
|
||||||
|
|
||||||
|
getDateOfCell (row, column) {
|
||||||
|
const offsetFromStart = row * 7 + (column - (this.showWeekNumber ? 1 : 0)) - this.offsetDay
|
||||||
|
return nextDate(this.startDate, offsetFromStart)
|
||||||
|
},
|
||||||
|
|
||||||
|
isWeekActive (cell) {
|
||||||
|
if (this.selectionMode !== 'week') return false
|
||||||
|
const newDate = new Date(this.year, this.month, 1)
|
||||||
|
const year = newDate.getFullYear()
|
||||||
|
const month = newDate.getMonth()
|
||||||
|
|
||||||
|
if (cell.type === 'prev-month') {
|
||||||
|
newDate.setMonth(month === 0 ? 11 : month - 1)
|
||||||
|
newDate.setFullYear(month === 0 ? year - 1 : year)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.type === 'next-month') {
|
||||||
|
newDate.setMonth(month === 11 ? 0 : month + 1)
|
||||||
|
newDate.setFullYear(month === 11 ? year + 1 : year)
|
||||||
|
}
|
||||||
|
|
||||||
|
newDate.setDate(parseInt(cell.text, 10))
|
||||||
|
|
||||||
|
if (isDate(this.value)) {
|
||||||
|
const dayOffset = (this.value.getDay() - this.firstDayOfWeek + 7) % 7 - 1
|
||||||
|
const weekDate = prevDate(this.value, dayOffset)
|
||||||
|
return weekDate.getTime() === newDate.getTime()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
|
markRange (minDate, maxDate) {
|
||||||
|
minDate = getDateTimestamp(minDate)
|
||||||
|
maxDate = getDateTimestamp(maxDate) || minDate;
|
||||||
|
[minDate, maxDate] = [Math.min(minDate, maxDate), Math.max(minDate, maxDate)]
|
||||||
|
|
||||||
|
const startDate = this.startDate
|
||||||
|
const rows = this.rows
|
||||||
|
for (let i = 0, k = rows.length; i < k; i++) {
|
||||||
|
const row = rows[i]
|
||||||
|
for (let j = 0, l = row.length; j < l; j++) {
|
||||||
|
if (this.showWeekNumber && j === 0) continue
|
||||||
|
|
||||||
|
const cell = row[j]
|
||||||
|
const index = i * 7 + j + (this.showWeekNumber ? -1 : 0)
|
||||||
|
const time = nextDate(startDate, index - this.offsetDay).getTime()
|
||||||
|
|
||||||
|
cell.inRange = minDate && time >= minDate && time <= maxDate
|
||||||
|
cell.start = minDate && time === minDate
|
||||||
|
cell.end = maxDate && time === maxDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMouseMove (event) {
|
||||||
|
if (!this.rangeState.selecting) return
|
||||||
|
|
||||||
|
let target = event.target
|
||||||
|
if (target.tagName === 'SPAN') {
|
||||||
|
target = target.parentNode.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName === 'DIV') {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName !== 'TD') return
|
||||||
|
|
||||||
|
const row = target.parentNode.rowIndex - 1
|
||||||
|
const column = target.cellIndex
|
||||||
|
|
||||||
|
// can not select disabled date
|
||||||
|
if (this.rows[row][column].disabled) return
|
||||||
|
|
||||||
|
// only update rangeState when mouse moves to a new cell
|
||||||
|
// this avoids frequent Date object creation and improves performance
|
||||||
|
if (row !== this.lastRow || column !== this.lastColumn) {
|
||||||
|
this.lastRow = row
|
||||||
|
this.lastColumn = column
|
||||||
|
this.$emit('changerange', {
|
||||||
|
minDate: this.minDate,
|
||||||
|
maxDate: this.maxDate,
|
||||||
|
rangeState: {
|
||||||
|
selecting: true,
|
||||||
|
endDate: this.getDateOfCell(row, column)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClick (event) {
|
||||||
|
let target = event.target
|
||||||
|
if (target.tagName === 'SPAN') {
|
||||||
|
target = target.parentNode.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName === 'DIV') {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.tagName !== 'TD') return
|
||||||
|
|
||||||
|
const row = target.parentNode.rowIndex - 1
|
||||||
|
const column = this.selectionMode === 'week' ? 1 : target.cellIndex
|
||||||
|
const cell = this.rows[row][column]
|
||||||
|
|
||||||
|
if (cell.disabled || cell.type === 'week') return
|
||||||
|
|
||||||
|
const newDate = this.getDateOfCell(row, column)
|
||||||
|
|
||||||
|
if (this.selectionMode === 'range') {
|
||||||
|
if (!this.rangeState.selecting) {
|
||||||
|
this.$emit('pick', { minDate: newDate, maxDate: null })
|
||||||
|
this.rangeState.selecting = true
|
||||||
|
} else {
|
||||||
|
if (newDate >= this.minDate) {
|
||||||
|
this.$emit('pick', { minDate: this.minDate, maxDate: newDate })
|
||||||
|
} else {
|
||||||
|
this.$emit('pick', { minDate: newDate, maxDate: this.minDate })
|
||||||
|
}
|
||||||
|
this.rangeState.selecting = false
|
||||||
|
}
|
||||||
|
} else if (this.selectionMode === 'day') {
|
||||||
|
this.$emit('pick', newDate)
|
||||||
|
} else if (this.selectionMode === 'week') {
|
||||||
|
const weekNumber = getWeekNumber(newDate)
|
||||||
|
const value = newDate.getFullYear() + 'w' + weekNumber
|
||||||
|
this.$emit('pick', {
|
||||||
|
year: newDate.getFullYear(),
|
||||||
|
week: weekNumber,
|
||||||
|
value: value,
|
||||||
|
date: newDate
|
||||||
|
})
|
||||||
|
} else if (this.selectionMode === 'dates') {
|
||||||
|
const value = this.value || []
|
||||||
|
const newValue = cell.selected
|
||||||
|
? removeFromArray(value, date => date.getTime() === newDate.getTime())
|
||||||
|
: [...value, newDate]
|
||||||
|
this.$emit('pick', newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
<template>
|
||||||
|
<table @click="handleMonthTableClick" @mousemove="handleMouseMove" class="el-month-table">
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(row, key) in rows" :key="key">
|
||||||
|
<td :class="getCellStyle(cell)" v-for="(cell, key) in row" :key="key">
|
||||||
|
<div>
|
||||||
|
<a class="cell">{{ t('el.datepicker.months.' + months[cell.text]) }}</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import { isDate, range, getDayCountOfMonth, nextDate } from 'element-ui/src/utils/date-util'
|
||||||
|
import { hasClass } from 'element-ui/src/utils/dom'
|
||||||
|
import { arrayFindIndex, coerceTruthyValueToArray, arrayFind } from 'element-ui/src/utils/util'
|
||||||
|
|
||||||
|
const datesInMonth = (year, month) => {
|
||||||
|
const numOfDays = getDayCountOfMonth(year, month)
|
||||||
|
const firstDay = new Date(year, month, 1)
|
||||||
|
return range(numOfDays).map(n => nextDate(firstDay, n))
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearDate = (date) => {
|
||||||
|
return new Date(date.getFullYear(), date.getMonth())
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMonthTimestamp = function (time) {
|
||||||
|
if (typeof time === 'number' || typeof time === 'string') {
|
||||||
|
return clearDate(new Date(time)).getTime()
|
||||||
|
} else if (time instanceof Date) {
|
||||||
|
return clearDate(time).getTime()
|
||||||
|
} else {
|
||||||
|
return NaN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
disabledDate: {},
|
||||||
|
value: {},
|
||||||
|
selectionMode: {
|
||||||
|
default: 'month'
|
||||||
|
},
|
||||||
|
minDate: {},
|
||||||
|
|
||||||
|
maxDate: {},
|
||||||
|
defaultValue: {
|
||||||
|
validator (val) {
|
||||||
|
// null or valid Date Object
|
||||||
|
return val === null || isDate(val) || (Array.isArray(val) && val.every(isDate))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
date: {},
|
||||||
|
rangeState: {
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
endDate: null,
|
||||||
|
selecting: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'rangeState.endDate' (newVal) {
|
||||||
|
this.markRange(this.minDate, newVal)
|
||||||
|
},
|
||||||
|
|
||||||
|
minDate (newVal, oldVal) {
|
||||||
|
if (getMonthTimestamp(newVal) !== getMonthTimestamp(oldVal)) {
|
||||||
|
this.markRange(this.minDate, this.maxDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maxDate (newVal, oldVal) {
|
||||||
|
if (getMonthTimestamp(newVal) !== getMonthTimestamp(oldVal)) {
|
||||||
|
this.markRange(this.minDate, this.maxDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
months: ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],
|
||||||
|
tableRows: [[], [], []],
|
||||||
|
lastRow: null,
|
||||||
|
lastColumn: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
cellMatchesDate (cell, date) {
|
||||||
|
const value = new Date(date)
|
||||||
|
return this.date.getFullYear() === value.getFullYear() && Number(cell.text) === value.getMonth()
|
||||||
|
},
|
||||||
|
getCellStyle (cell) {
|
||||||
|
const style = {}
|
||||||
|
const year = this.date.getFullYear()
|
||||||
|
const today = new Date()
|
||||||
|
const month = cell.text
|
||||||
|
const defaultValue = this.defaultValue ? Array.isArray(this.defaultValue) ? this.defaultValue : [this.defaultValue] : []
|
||||||
|
style.disabled = typeof this.disabledDate === 'function'
|
||||||
|
? datesInMonth(year, month).every(this.disabledDate)
|
||||||
|
: false
|
||||||
|
style.current = arrayFindIndex(coerceTruthyValueToArray(this.value), date => date.getFullYear() === year && date.getMonth() === month) >= 0
|
||||||
|
style.today = today.getFullYear() === year && today.getMonth() === month
|
||||||
|
style.default = defaultValue.some(date => this.cellMatchesDate(cell, date))
|
||||||
|
|
||||||
|
if (cell.inRange) {
|
||||||
|
style['in-range'] = true
|
||||||
|
|
||||||
|
if (cell.start) {
|
||||||
|
style['start-date'] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.end) {
|
||||||
|
style['end-date'] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
getMonthOfCell (month) {
|
||||||
|
const year = this.date.getFullYear()
|
||||||
|
return new Date(year, month, 1)
|
||||||
|
},
|
||||||
|
markRange (minDate, maxDate) {
|
||||||
|
minDate = getMonthTimestamp(minDate)
|
||||||
|
maxDate = getMonthTimestamp(maxDate) || minDate;
|
||||||
|
[minDate, maxDate] = [Math.min(minDate, maxDate), Math.max(minDate, maxDate)]
|
||||||
|
const rows = this.rows
|
||||||
|
for (let i = 0, k = rows.length; i < k; i++) {
|
||||||
|
const row = rows[i]
|
||||||
|
for (let j = 0, l = row.length; j < l; j++) {
|
||||||
|
const cell = row[j]
|
||||||
|
const index = i * 4 + j
|
||||||
|
const time = new Date(this.date.getFullYear(), index).getTime()
|
||||||
|
|
||||||
|
cell.inRange = minDate && time >= minDate && time <= maxDate
|
||||||
|
cell.start = minDate && time === minDate
|
||||||
|
cell.end = maxDate && time === maxDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleMouseMove (event) {
|
||||||
|
if (!this.rangeState.selecting) return
|
||||||
|
|
||||||
|
let target = event.target
|
||||||
|
if (target.tagName === 'A') {
|
||||||
|
target = target.parentNode.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName === 'DIV') {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName !== 'TD') return
|
||||||
|
|
||||||
|
const row = target.parentNode.rowIndex
|
||||||
|
const column = target.cellIndex
|
||||||
|
// can not select disabled date
|
||||||
|
if (this.rows[row][column].disabled) return
|
||||||
|
|
||||||
|
// only update rangeState when mouse moves to a new cell
|
||||||
|
// this avoids frequent Date object creation and improves performance
|
||||||
|
if (row !== this.lastRow || column !== this.lastColumn) {
|
||||||
|
this.lastRow = row
|
||||||
|
this.lastColumn = column
|
||||||
|
this.$emit('changerange', {
|
||||||
|
minDate: this.minDate,
|
||||||
|
maxDate: this.maxDate,
|
||||||
|
rangeState: {
|
||||||
|
selecting: true,
|
||||||
|
endDate: this.getMonthOfCell(row * 4 + column)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleMonthTableClick (event) {
|
||||||
|
let target = event.target
|
||||||
|
if (target.tagName === 'A') {
|
||||||
|
target = target.parentNode.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName === 'DIV') {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
if (target.tagName !== 'TD') return
|
||||||
|
if (hasClass(target, 'disabled')) return
|
||||||
|
const column = target.cellIndex
|
||||||
|
const row = target.parentNode.rowIndex
|
||||||
|
const month = row * 4 + column
|
||||||
|
const newDate = this.getMonthOfCell(month)
|
||||||
|
if (this.selectionMode === 'range') {
|
||||||
|
if (!this.rangeState.selecting) {
|
||||||
|
this.$emit('pick', { minDate: newDate, maxDate: null })
|
||||||
|
this.rangeState.selecting = true
|
||||||
|
} else {
|
||||||
|
if (newDate >= this.minDate) {
|
||||||
|
this.$emit('pick', { minDate: this.minDate, maxDate: newDate })
|
||||||
|
} else {
|
||||||
|
this.$emit('pick', { minDate: newDate, maxDate: this.minDate })
|
||||||
|
}
|
||||||
|
this.rangeState.selecting = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$emit('pick', month)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
rows () {
|
||||||
|
// TODO: refactory rows / getCellClasses
|
||||||
|
const rows = this.tableRows
|
||||||
|
const disabledDate = this.disabledDate
|
||||||
|
const selectedDate = []
|
||||||
|
const now = getMonthTimestamp(new Date())
|
||||||
|
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const row = rows[i]
|
||||||
|
for (let j = 0; j < 4; j++) {
|
||||||
|
let cell = row[j]
|
||||||
|
if (!cell) {
|
||||||
|
cell = { row: i, column: j, type: 'normal', inRange: false, start: false, end: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.type = 'normal'
|
||||||
|
|
||||||
|
const index = i * 4 + j
|
||||||
|
const time = new Date(this.date.getFullYear(), index).getTime()
|
||||||
|
cell.inRange = time >= getMonthTimestamp(this.minDate) && time <= getMonthTimestamp(this.maxDate)
|
||||||
|
cell.start = this.minDate && time === getMonthTimestamp(this.minDate)
|
||||||
|
cell.end = this.maxDate && time === getMonthTimestamp(this.maxDate)
|
||||||
|
const isToday = time === now
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
cell.type = 'today'
|
||||||
|
}
|
||||||
|
cell.text = index
|
||||||
|
const cellDate = new Date(time)
|
||||||
|
cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate)
|
||||||
|
cell.selected = arrayFind(selectedDate, date => date.getTime() === cellDate.getTime())
|
||||||
|
|
||||||
|
this.$set(row, j, cell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,304 @@
|
|||||||
|
<template>
|
||||||
|
<div class="el-time-spinner" :class="{ 'has-seconds': showSeconds }">
|
||||||
|
<template v-if="!arrowControl">
|
||||||
|
<el-scrollbar
|
||||||
|
@mouseenter.native="emitSelectRange('hours')"
|
||||||
|
@mousemove.native="adjustCurrentSpinner('hours')"
|
||||||
|
class="el-time-spinner__wrapper"
|
||||||
|
wrap-style="max-height: inherit;"
|
||||||
|
view-class="el-time-spinner__list"
|
||||||
|
noresize
|
||||||
|
tag="ul"
|
||||||
|
ref="hours">
|
||||||
|
<li
|
||||||
|
@click="handleClick('hours', { value: hour, disabled: disabled })"
|
||||||
|
v-for="(disabled, hour) in hoursList"
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:key="hour"
|
||||||
|
:class="{ 'active': hour === hours, 'disabled': disabled }">{{ ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) }}{{ amPm(hour) }}</li>
|
||||||
|
</el-scrollbar>
|
||||||
|
<el-scrollbar
|
||||||
|
@mouseenter.native="emitSelectRange('minutes')"
|
||||||
|
@mousemove.native="adjustCurrentSpinner('minutes')"
|
||||||
|
class="el-time-spinner__wrapper"
|
||||||
|
wrap-style="max-height: inherit;"
|
||||||
|
view-class="el-time-spinner__list"
|
||||||
|
noresize
|
||||||
|
tag="ul"
|
||||||
|
ref="minutes">
|
||||||
|
<li
|
||||||
|
@click="handleClick('minutes', { value: key, disabled: false })"
|
||||||
|
v-for="(enabled, key) in minutesList"
|
||||||
|
:key="key"
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:class="{ 'active': key === minutes, disabled: !enabled }">{{ ('0' + key).slice(-2) }}</li>
|
||||||
|
</el-scrollbar>
|
||||||
|
<el-scrollbar
|
||||||
|
v-show="showSeconds"
|
||||||
|
@mouseenter.native="emitSelectRange('seconds')"
|
||||||
|
@mousemove.native="adjustCurrentSpinner('seconds')"
|
||||||
|
class="el-time-spinner__wrapper"
|
||||||
|
wrap-style="max-height: inherit;"
|
||||||
|
view-class="el-time-spinner__list"
|
||||||
|
noresize
|
||||||
|
tag="ul"
|
||||||
|
ref="seconds">
|
||||||
|
<li
|
||||||
|
@click="handleClick('seconds', { value: key, disabled: false })"
|
||||||
|
v-for="(second, key) in 60"
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:class="{ 'active': key === seconds }"
|
||||||
|
:key="key">{{ ('0' + key).slice(-2) }}</li>
|
||||||
|
</el-scrollbar>
|
||||||
|
</template>
|
||||||
|
<template v-if="arrowControl">
|
||||||
|
<div
|
||||||
|
@mouseenter="emitSelectRange('hours')"
|
||||||
|
class="el-time-spinner__wrapper is-arrow">
|
||||||
|
<i v-repeat-click="decrease" class="el-time-spinner__arrow el-icon-arrow-up"></i>
|
||||||
|
<i v-repeat-click="increase" class="el-time-spinner__arrow el-icon-arrow-down"></i>
|
||||||
|
<ul class="el-time-spinner__list" ref="hours">
|
||||||
|
<li
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:class="{ 'active': hour === hours, 'disabled': hoursList[hour] }"
|
||||||
|
v-for="(hour, key) in arrowHourList"
|
||||||
|
:key="key">{{ hour === undefined ? '' : ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) + amPm(hour) }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@mouseenter="emitSelectRange('minutes')"
|
||||||
|
class="el-time-spinner__wrapper is-arrow">
|
||||||
|
<i v-repeat-click="decrease" class="el-time-spinner__arrow el-icon-arrow-up"></i>
|
||||||
|
<i v-repeat-click="increase" class="el-time-spinner__arrow el-icon-arrow-down"></i>
|
||||||
|
<ul class="el-time-spinner__list" ref="minutes">
|
||||||
|
<li
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:class="{ 'active': minute === minutes }"
|
||||||
|
v-for="(minute, key) in arrowMinuteList"
|
||||||
|
:key="key">
|
||||||
|
{{ minute === undefined ? '' : ('0' + minute).slice(-2) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@mouseenter="emitSelectRange('seconds')"
|
||||||
|
class="el-time-spinner__wrapper is-arrow"
|
||||||
|
v-if="showSeconds">
|
||||||
|
<i v-repeat-click="decrease" class="el-time-spinner__arrow el-icon-arrow-up"></i>
|
||||||
|
<i v-repeat-click="increase" class="el-time-spinner__arrow el-icon-arrow-down"></i>
|
||||||
|
<ul class="el-time-spinner__list" ref="seconds">
|
||||||
|
<li
|
||||||
|
v-for="(second, key) in arrowSecondList"
|
||||||
|
class="el-time-spinner__item"
|
||||||
|
:class="{ 'active': second === seconds }"
|
||||||
|
:key="key">
|
||||||
|
{{ second === undefined ? '' : ('0' + second).slice(-2) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import { getRangeHours, getRangeMinutes, modifyTime } from 'element-ui/src/utils/date-util'
|
||||||
|
import ElScrollbar from 'element-ui/packages/scrollbar'
|
||||||
|
import RepeatClick from 'element-ui/src/directives/repeat-click'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { ElScrollbar },
|
||||||
|
|
||||||
|
directives: {
|
||||||
|
repeatClick: RepeatClick
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
date: {},
|
||||||
|
defaultValue: {}, // reserved for future use
|
||||||
|
showSeconds: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
arrowControl: Boolean,
|
||||||
|
amPmMode: {
|
||||||
|
type: String,
|
||||||
|
default: '' // 'a': am/pm; 'A': AM/PM
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
hours () {
|
||||||
|
return this.date.getHours()
|
||||||
|
},
|
||||||
|
minutes () {
|
||||||
|
return this.date.getMinutes()
|
||||||
|
},
|
||||||
|
seconds () {
|
||||||
|
return this.date.getSeconds()
|
||||||
|
},
|
||||||
|
hoursList () {
|
||||||
|
return getRangeHours(this.selectableRange)
|
||||||
|
},
|
||||||
|
minutesList () {
|
||||||
|
return getRangeMinutes(this.selectableRange, this.hours)
|
||||||
|
},
|
||||||
|
arrowHourList () {
|
||||||
|
const hours = this.hours
|
||||||
|
return [
|
||||||
|
hours > 0 ? hours - 1 : undefined,
|
||||||
|
hours,
|
||||||
|
hours < 23 ? hours + 1 : undefined
|
||||||
|
]
|
||||||
|
},
|
||||||
|
arrowMinuteList () {
|
||||||
|
const minutes = this.minutes
|
||||||
|
return [
|
||||||
|
minutes > 0 ? minutes - 1 : undefined,
|
||||||
|
minutes,
|
||||||
|
minutes < 59 ? minutes + 1 : undefined
|
||||||
|
]
|
||||||
|
},
|
||||||
|
arrowSecondList () {
|
||||||
|
const seconds = this.seconds
|
||||||
|
return [
|
||||||
|
seconds > 0 ? seconds - 1 : undefined,
|
||||||
|
seconds,
|
||||||
|
seconds < 59 ? seconds + 1 : undefined
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
selectableRange: [],
|
||||||
|
currentScrollbar: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
!this.arrowControl && this.bindScrollEvent()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
increase () {
|
||||||
|
this.scrollDown(1)
|
||||||
|
},
|
||||||
|
|
||||||
|
decrease () {
|
||||||
|
this.scrollDown(-1)
|
||||||
|
},
|
||||||
|
|
||||||
|
modifyDateField (type, value) {
|
||||||
|
switch (type) {
|
||||||
|
case 'hours': this.$emit('change', modifyTime(this.date, value, this.minutes, this.seconds)); break
|
||||||
|
case 'minutes': this.$emit('change', modifyTime(this.date, this.hours, value, this.seconds)); break
|
||||||
|
case 'seconds': this.$emit('change', modifyTime(this.date, this.hours, this.minutes, value)); break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClick (type, { value, disabled }) {
|
||||||
|
if (!disabled) {
|
||||||
|
this.modifyDateField(type, value)
|
||||||
|
this.emitSelectRange(type)
|
||||||
|
this.adjustSpinner(type, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emitSelectRange (type) {
|
||||||
|
if (type === 'hours') {
|
||||||
|
this.$emit('select-range', 0, 2)
|
||||||
|
} else if (type === 'minutes') {
|
||||||
|
this.$emit('select-range', 3, 5)
|
||||||
|
} else if (type === 'seconds') {
|
||||||
|
this.$emit('select-range', 6, 8)
|
||||||
|
}
|
||||||
|
this.currentScrollbar = type
|
||||||
|
},
|
||||||
|
|
||||||
|
bindScrollEvent () {
|
||||||
|
const bindFuntion = (type) => {
|
||||||
|
this.$refs[type].wrap.onscroll = (e) => {
|
||||||
|
// TODO: scroll is emitted when set scrollTop programatically
|
||||||
|
// should find better solutions in the future!
|
||||||
|
this.handleScroll(type, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bindFuntion('hours')
|
||||||
|
bindFuntion('minutes')
|
||||||
|
bindFuntion('seconds')
|
||||||
|
},
|
||||||
|
|
||||||
|
handleScroll (type) {
|
||||||
|
const value = Math.min(Math.round((this.$refs[type].wrap.scrollTop - (this.scrollBarHeight(type) * 0.5 - 10) / this.typeItemHeight(type) + 3) / this.typeItemHeight(type)), (type === 'hours' ? 23 : 59))
|
||||||
|
this.modifyDateField(type, value)
|
||||||
|
},
|
||||||
|
|
||||||
|
// NOTE: used by datetime / date-range panel
|
||||||
|
// renamed from adjustScrollTop
|
||||||
|
// should try to refactory it
|
||||||
|
adjustSpinners () {
|
||||||
|
this.adjustSpinner('hours', this.hours)
|
||||||
|
this.adjustSpinner('minutes', this.minutes)
|
||||||
|
this.adjustSpinner('seconds', this.seconds)
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustCurrentSpinner (type) {
|
||||||
|
this.adjustSpinner(type, this[type])
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustSpinner (type, value) {
|
||||||
|
if (this.arrowControl) return
|
||||||
|
const el = this.$refs[type].wrap
|
||||||
|
if (el) {
|
||||||
|
el.scrollTop = Math.max(0, value * this.typeItemHeight(type))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
scrollDown (step) {
|
||||||
|
if (!this.currentScrollbar) {
|
||||||
|
this.emitSelectRange('hours')
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = this.currentScrollbar
|
||||||
|
const hoursList = this.hoursList
|
||||||
|
let now = this[label]
|
||||||
|
|
||||||
|
if (this.currentScrollbar === 'hours') {
|
||||||
|
let total = Math.abs(step)
|
||||||
|
step = step > 0 ? 1 : -1
|
||||||
|
let length = hoursList.length
|
||||||
|
while (length-- && total) {
|
||||||
|
now = (now + step + hoursList.length) % hoursList.length
|
||||||
|
if (hoursList[now]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
total--
|
||||||
|
}
|
||||||
|
if (hoursList[now]) return
|
||||||
|
} else {
|
||||||
|
now = (now + step + 60) % 60
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modifyDateField(label, now)
|
||||||
|
this.adjustSpinner(label, now)
|
||||||
|
this.$nextTick(() => this.emitSelectRange(this.currentScrollbar))
|
||||||
|
},
|
||||||
|
amPm (hour) {
|
||||||
|
const shouldShowAmPm = this.amPmMode.toLowerCase() === 'a'
|
||||||
|
if (!shouldShowAmPm) return ''
|
||||||
|
const isCapital = this.amPmMode === 'A'
|
||||||
|
let content = (hour < 12) ? ' am' : ' pm'
|
||||||
|
if (isCapital) content = content.toUpperCase()
|
||||||
|
return content
|
||||||
|
},
|
||||||
|
typeItemHeight (type) {
|
||||||
|
return this.$refs[type].$el.querySelector('li').offsetHeight
|
||||||
|
},
|
||||||
|
scrollBarHeight (type) {
|
||||||
|
return this.$refs[type].$el.offsetHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<table @click="handleYearTableClick" class="el-year-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 0)">
|
||||||
|
<a class="cell">{{ startYear }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 1)">
|
||||||
|
<a class="cell">{{ startYear + 1 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 2)">
|
||||||
|
<a class="cell">{{ startYear + 2 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 3)">
|
||||||
|
<a class="cell">{{ startYear + 3 }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 4)">
|
||||||
|
<a class="cell">{{ startYear + 4 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 5)">
|
||||||
|
<a class="cell">{{ startYear + 5 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 6)">
|
||||||
|
<a class="cell">{{ startYear + 6 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 7)">
|
||||||
|
<a class="cell">{{ startYear + 7 }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 8)">
|
||||||
|
<a class="cell">{{ startYear + 8 }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="available" :class="getCellStyle(startYear + 9)">
|
||||||
|
<a class="cell">{{ startYear + 9 }}</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import { hasClass } from 'element-ui/src/utils/dom'
|
||||||
|
import { isDate, range, nextDate, getDayCountOfYear } from 'element-ui/src/utils/date-util'
|
||||||
|
import { arrayFindIndex, coerceTruthyValueToArray } from 'element-ui/src/utils/util'
|
||||||
|
|
||||||
|
const datesInYear = year => {
|
||||||
|
const numOfDays = getDayCountOfYear(year)
|
||||||
|
const firstDay = new Date(year, 0, 1)
|
||||||
|
return range(numOfDays).map(n => nextDate(firstDay, n))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
disabledDate: {},
|
||||||
|
value: {},
|
||||||
|
defaultValue: {
|
||||||
|
validator (val) {
|
||||||
|
// null or valid Date Object
|
||||||
|
return val === null || (val instanceof Date && isDate(val))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
date: {}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
startYear () {
|
||||||
|
return Math.floor(this.date.getFullYear() / 10) * 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getCellStyle (year) {
|
||||||
|
const style = {}
|
||||||
|
const today = new Date()
|
||||||
|
|
||||||
|
style.disabled = typeof this.disabledDate === 'function'
|
||||||
|
? datesInYear(year).every(this.disabledDate)
|
||||||
|
: false
|
||||||
|
style.current = arrayFindIndex(coerceTruthyValueToArray(this.value), date => date.getFullYear() === year) >= 0
|
||||||
|
style.today = today.getFullYear() === year
|
||||||
|
style.default = this.defaultValue && this.defaultValue.getFullYear() === year
|
||||||
|
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
|
||||||
|
handleYearTableClick (event) {
|
||||||
|
const target = event.target
|
||||||
|
if (target.tagName === 'A') {
|
||||||
|
if (hasClass(target.parentNode, 'disabled')) return
|
||||||
|
const year = target.textContent || target.innerText
|
||||||
|
this.$emit('pick', Number(year))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,680 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||||
|
<div
|
||||||
|
v-show="visible"
|
||||||
|
class="el-picker-panel el-date-range-picker el-popper"
|
||||||
|
:class="[{
|
||||||
|
'has-sidebar': $slots.sidebar || shortcuts,
|
||||||
|
'has-time': showTime
|
||||||
|
}, popperClass]">
|
||||||
|
<div class="el-picker-panel__body-wrapper">
|
||||||
|
<slot name="sidebar" class="el-picker-panel__sidebar"></slot>
|
||||||
|
<div class="el-picker-panel__sidebar" v-if="shortcuts">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-picker-panel__shortcut"
|
||||||
|
v-for="(shortcut, key) in shortcuts"
|
||||||
|
:key="key"
|
||||||
|
@click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__body">
|
||||||
|
<div class="el-date-range-picker__time-header" v-if="showTime">
|
||||||
|
<span class="el-date-range-picker__editors-wrap">
|
||||||
|
<span class="el-date-range-picker__time-picker-wrap">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
:disabled="rangeState.selecting"
|
||||||
|
ref="minInput"
|
||||||
|
:placeholder="t('el.datepicker.startDate')"
|
||||||
|
class="el-date-range-picker__editor"
|
||||||
|
:value="minVisibleDate"
|
||||||
|
@input="val => handleDateInput(val, 'min')"
|
||||||
|
@change="val => handleDateChange(val, 'min')" />
|
||||||
|
</span>
|
||||||
|
<span class="el-date-range-picker__time-picker-wrap" v-clickoutside="handleMinTimeClose">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
class="el-date-range-picker__editor"
|
||||||
|
:disabled="rangeState.selecting"
|
||||||
|
:placeholder="t('el.datepicker.startTime')"
|
||||||
|
:value="minVisibleTime"
|
||||||
|
@focus="minTimePickerVisible = true"
|
||||||
|
@input="val => handleTimeInput(val, 'min')"
|
||||||
|
@change="val => handleTimeChange(val, 'min')" />
|
||||||
|
<time-picker
|
||||||
|
ref="minTimePicker"
|
||||||
|
@pick="handleMinTimePick"
|
||||||
|
:time-arrow-control="arrowControl"
|
||||||
|
:visible="minTimePickerVisible"
|
||||||
|
@mounted="$refs.minTimePicker.format=timeFormat">
|
||||||
|
</time-picker>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="el-icon-arrow-right"></span>
|
||||||
|
<span class="el-date-range-picker__editors-wrap is-right">
|
||||||
|
<span class="el-date-range-picker__time-picker-wrap">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
class="el-date-range-picker__editor"
|
||||||
|
:disabled="rangeState.selecting"
|
||||||
|
:placeholder="t('el.datepicker.endDate')"
|
||||||
|
:value="maxVisibleDate"
|
||||||
|
:readonly="!minDate"
|
||||||
|
@input="val => handleDateInput(val, 'max')"
|
||||||
|
@change="val => handleDateChange(val, 'max')" />
|
||||||
|
</span>
|
||||||
|
<span class="el-date-range-picker__time-picker-wrap" v-clickoutside="handleMaxTimeClose">
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
class="el-date-range-picker__editor"
|
||||||
|
:disabled="rangeState.selecting"
|
||||||
|
:placeholder="t('el.datepicker.endTime')"
|
||||||
|
:value="maxVisibleTime"
|
||||||
|
:readonly="!minDate"
|
||||||
|
@focus="minDate && (maxTimePickerVisible = true)"
|
||||||
|
@input="val => handleTimeInput(val, 'max')"
|
||||||
|
@change="val => handleTimeChange(val, 'max')" />
|
||||||
|
<time-picker
|
||||||
|
ref="maxTimePicker"
|
||||||
|
@pick="handleMaxTimePick"
|
||||||
|
:time-arrow-control="arrowControl"
|
||||||
|
:visible="maxTimePickerVisible"
|
||||||
|
@mounted="$refs.maxTimePicker.format=timeFormat">
|
||||||
|
</time-picker>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__content el-date-range-picker__content is-left">
|
||||||
|
<div class="el-date-range-picker__header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="leftPrevYear"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="leftPrevMonth"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="leftNextYear"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
:disabled="!enableYearArrow"
|
||||||
|
:class="{ 'is-disabled': !enableYearArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="leftNextMonth"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
:disabled="!enableMonthArrow"
|
||||||
|
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
|
||||||
|
<div>{{ leftLabel }}</div>
|
||||||
|
</div>
|
||||||
|
<date-table
|
||||||
|
selection-mode="range"
|
||||||
|
:date="leftDate"
|
||||||
|
:default-value="defaultValue"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
:range-state="rangeState"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
:cell-class-name="cellClassName"
|
||||||
|
@changerange="handleChangeRange"
|
||||||
|
:first-day-of-week="firstDayOfWeek"
|
||||||
|
@pick="handleRangePick">
|
||||||
|
</date-table>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__content el-date-range-picker__content is-right">
|
||||||
|
<div class="el-date-range-picker__header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="rightPrevYear"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
:disabled="!enableYearArrow"
|
||||||
|
:class="{ 'is-disabled': !enableYearArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="rightPrevMonth"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
:disabled="!enableMonthArrow"
|
||||||
|
:class="{ 'is-disabled': !enableMonthArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="rightNextYear"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="rightNextMonth"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
|
||||||
|
<div>{{ rightLabel }}</div>
|
||||||
|
</div>
|
||||||
|
<date-table
|
||||||
|
selection-mode="range"
|
||||||
|
:date="rightDate"
|
||||||
|
:default-value="defaultValue"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
:range-state="rangeState"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
:cell-class-name="cellClassName"
|
||||||
|
@changerange="handleChangeRange"
|
||||||
|
:first-day-of-week="firstDayOfWeek"
|
||||||
|
@pick="handleRangePick">
|
||||||
|
</date-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__footer" v-if="showTime">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
class="el-picker-panel__link-btn"
|
||||||
|
@click="handleClear">
|
||||||
|
{{ t('el.datepicker.clear') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
plain
|
||||||
|
size="mini"
|
||||||
|
class="el-picker-panel__link-btn"
|
||||||
|
:disabled="btnDisabled"
|
||||||
|
@click="handleConfirm(false)">
|
||||||
|
{{ t('el.datepicker.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import {
|
||||||
|
formatDate,
|
||||||
|
parseDate,
|
||||||
|
isDate,
|
||||||
|
modifyDate,
|
||||||
|
modifyTime,
|
||||||
|
modifyWithTimeString,
|
||||||
|
prevYear,
|
||||||
|
nextYear,
|
||||||
|
prevMonth,
|
||||||
|
nextMonth,
|
||||||
|
nextDate,
|
||||||
|
extractDateFormat,
|
||||||
|
extractTimeFormat
|
||||||
|
} from 'element-ui/src/utils/date-util'
|
||||||
|
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import TimePicker from './time'
|
||||||
|
import DateTable from '../basic/date-table'
|
||||||
|
import ElInput from 'element-ui/packages/input'
|
||||||
|
import ElButton from 'element-ui/packages/button'
|
||||||
|
|
||||||
|
const calcDefaultValue = (defaultValue) => {
|
||||||
|
if (Array.isArray(defaultValue)) {
|
||||||
|
return [new Date(defaultValue[0]), new Date(defaultValue[1])]
|
||||||
|
} else if (defaultValue) {
|
||||||
|
return [new Date(defaultValue), nextDate(new Date(defaultValue), 1)]
|
||||||
|
} else {
|
||||||
|
return [new Date(), nextDate(new Date(), 1)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
directives: { Clickoutside },
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
btnDisabled () {
|
||||||
|
return !(this.minDate && this.maxDate && !this.selecting && this.isValidValue([this.minDate, this.maxDate]))
|
||||||
|
},
|
||||||
|
|
||||||
|
leftLabel () {
|
||||||
|
return this.leftDate.getFullYear() + ' ' + this.t('el.datepicker.year') + ' ' + this.t(`el.datepicker.month${this.leftDate.getMonth() + 1}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
rightLabel () {
|
||||||
|
return this.rightDate.getFullYear() + ' ' + this.t('el.datepicker.year') + ' ' + this.t(`el.datepicker.month${this.rightDate.getMonth() + 1}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
leftYear () {
|
||||||
|
return this.leftDate.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
leftMonth () {
|
||||||
|
return this.leftDate.getMonth()
|
||||||
|
},
|
||||||
|
|
||||||
|
leftMonthDate () {
|
||||||
|
return this.leftDate.getDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
rightYear () {
|
||||||
|
return this.rightDate.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
rightMonth () {
|
||||||
|
return this.rightDate.getMonth()
|
||||||
|
},
|
||||||
|
|
||||||
|
rightMonthDate () {
|
||||||
|
return this.rightDate.getDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
minVisibleDate () {
|
||||||
|
if (this.dateUserInput.min !== null) return this.dateUserInput.min
|
||||||
|
if (this.minDate) return formatDate(this.minDate, this.dateFormat)
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
|
||||||
|
maxVisibleDate () {
|
||||||
|
if (this.dateUserInput.max !== null) return this.dateUserInput.max
|
||||||
|
if (this.maxDate || this.minDate) return formatDate(this.maxDate || this.minDate, this.dateFormat)
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
|
||||||
|
minVisibleTime () {
|
||||||
|
if (this.timeUserInput.min !== null) return this.timeUserInput.min
|
||||||
|
if (this.minDate) return formatDate(this.minDate, this.timeFormat)
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
|
||||||
|
maxVisibleTime () {
|
||||||
|
if (this.timeUserInput.max !== null) return this.timeUserInput.max
|
||||||
|
if (this.maxDate || this.minDate) return formatDate(this.maxDate || this.minDate, this.timeFormat)
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
|
||||||
|
timeFormat () {
|
||||||
|
if (this.format) {
|
||||||
|
return extractTimeFormat(this.format)
|
||||||
|
} else {
|
||||||
|
return 'HH:mm:ss'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dateFormat () {
|
||||||
|
if (this.format) {
|
||||||
|
return extractDateFormat(this.format)
|
||||||
|
} else {
|
||||||
|
return 'yyyy-MM-dd'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
enableMonthArrow () {
|
||||||
|
const nextMonth = (this.leftMonth + 1) % 12
|
||||||
|
const yearOffset = this.leftMonth + 1 >= 12 ? 1 : 0
|
||||||
|
return this.unlinkPanels && new Date(this.leftYear + yearOffset, nextMonth) < new Date(this.rightYear, this.rightMonth)
|
||||||
|
},
|
||||||
|
|
||||||
|
enableYearArrow () {
|
||||||
|
return this.unlinkPanels && this.rightYear * 12 + this.rightMonth - (this.leftYear * 12 + this.leftMonth + 1) >= 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
value: [],
|
||||||
|
defaultValue: null,
|
||||||
|
defaultTime: null,
|
||||||
|
minDate: '',
|
||||||
|
maxDate: '',
|
||||||
|
leftDate: new Date(),
|
||||||
|
rightDate: nextMonth(new Date()),
|
||||||
|
rangeState: {
|
||||||
|
endDate: null,
|
||||||
|
selecting: false,
|
||||||
|
row: null,
|
||||||
|
column: null
|
||||||
|
},
|
||||||
|
showTime: false,
|
||||||
|
shortcuts: '',
|
||||||
|
visible: '',
|
||||||
|
disabledDate: '',
|
||||||
|
cellClassName: '',
|
||||||
|
firstDayOfWeek: 7,
|
||||||
|
minTimePickerVisible: false,
|
||||||
|
maxTimePickerVisible: false,
|
||||||
|
format: '',
|
||||||
|
arrowControl: false,
|
||||||
|
unlinkPanels: false,
|
||||||
|
dateUserInput: {
|
||||||
|
min: null,
|
||||||
|
max: null
|
||||||
|
},
|
||||||
|
timeUserInput: {
|
||||||
|
min: null,
|
||||||
|
max: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
minDate (val) {
|
||||||
|
this.dateUserInput.min = null
|
||||||
|
this.timeUserInput.min = null
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.maxTimePicker && this.maxDate && this.maxDate < this.minDate) {
|
||||||
|
const format = 'HH:mm:ss'
|
||||||
|
this.$refs.maxTimePicker.selectableRange = [
|
||||||
|
[
|
||||||
|
parseDate(formatDate(this.minDate, format), format),
|
||||||
|
parseDate('23:59:59', format)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (val && this.$refs.minTimePicker) {
|
||||||
|
this.$refs.minTimePicker.date = val
|
||||||
|
this.$refs.minTimePicker.value = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maxDate (val) {
|
||||||
|
this.dateUserInput.max = null
|
||||||
|
this.timeUserInput.max = null
|
||||||
|
if (val && this.$refs.maxTimePicker) {
|
||||||
|
this.$refs.maxTimePicker.date = val
|
||||||
|
this.$refs.maxTimePicker.value = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
minTimePickerVisible (val) {
|
||||||
|
if (val) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.minTimePicker.date = this.minDate
|
||||||
|
this.$refs.minTimePicker.value = this.minDate
|
||||||
|
this.$refs.minTimePicker.adjustSpinners()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maxTimePickerVisible (val) {
|
||||||
|
if (val) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.maxTimePicker.date = this.maxDate
|
||||||
|
this.$refs.maxTimePicker.value = this.maxDate
|
||||||
|
this.$refs.maxTimePicker.adjustSpinners()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
value (newVal) {
|
||||||
|
if (!newVal) {
|
||||||
|
this.minDate = null
|
||||||
|
this.maxDate = null
|
||||||
|
} else if (Array.isArray(newVal)) {
|
||||||
|
this.minDate = isDate(newVal[0]) ? new Date(newVal[0]) : null
|
||||||
|
this.maxDate = isDate(newVal[1]) ? new Date(newVal[1]) : null
|
||||||
|
if (this.minDate) {
|
||||||
|
this.leftDate = this.minDate
|
||||||
|
if (this.unlinkPanels && this.maxDate) {
|
||||||
|
const minDateYear = this.minDate.getFullYear()
|
||||||
|
const minDateMonth = this.minDate.getMonth()
|
||||||
|
const maxDateYear = this.maxDate.getFullYear()
|
||||||
|
const maxDateMonth = this.maxDate.getMonth()
|
||||||
|
this.rightDate = minDateYear === maxDateYear && minDateMonth === maxDateMonth
|
||||||
|
? nextMonth(this.maxDate)
|
||||||
|
: this.maxDate
|
||||||
|
} else {
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.leftDate = calcDefaultValue(this.defaultValue)[0]
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultValue (val) {
|
||||||
|
if (!Array.isArray(this.value)) {
|
||||||
|
const [left, right] = calcDefaultValue(val)
|
||||||
|
this.leftDate = left
|
||||||
|
this.rightDate = val && val[1] && this.unlinkPanels
|
||||||
|
? right
|
||||||
|
: nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleClear () {
|
||||||
|
this.minDate = null
|
||||||
|
this.maxDate = null
|
||||||
|
this.leftDate = calcDefaultValue(this.defaultValue)[0]
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
this.$emit('pick', null)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChangeRange (val) {
|
||||||
|
this.minDate = val.minDate
|
||||||
|
this.maxDate = val.maxDate
|
||||||
|
this.rangeState = val.rangeState
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDateInput (value, type) {
|
||||||
|
this.dateUserInput[type] = value
|
||||||
|
if (value.length !== this.dateFormat.length) return
|
||||||
|
const parsedValue = parseDate(value, this.dateFormat)
|
||||||
|
|
||||||
|
if (parsedValue) {
|
||||||
|
if (typeof this.disabledDate === 'function' &&
|
||||||
|
this.disabledDate(new Date(parsedValue))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (type === 'min') {
|
||||||
|
this.minDate = modifyDate(this.minDate || new Date(), parsedValue.getFullYear(), parsedValue.getMonth(), parsedValue.getDate())
|
||||||
|
this.leftDate = new Date(parsedValue)
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.maxDate = modifyDate(this.maxDate || new Date(), parsedValue.getFullYear(), parsedValue.getMonth(), parsedValue.getDate())
|
||||||
|
this.rightDate = new Date(parsedValue)
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.leftDate = prevMonth(parsedValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDateChange (value, type) {
|
||||||
|
const parsedValue = parseDate(value, this.dateFormat)
|
||||||
|
if (parsedValue) {
|
||||||
|
if (type === 'min') {
|
||||||
|
this.minDate = modifyDate(this.minDate, parsedValue.getFullYear(), parsedValue.getMonth(), parsedValue.getDate())
|
||||||
|
if (this.minDate > this.maxDate) {
|
||||||
|
this.maxDate = this.minDate
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.maxDate = modifyDate(this.maxDate, parsedValue.getFullYear(), parsedValue.getMonth(), parsedValue.getDate())
|
||||||
|
if (this.maxDate < this.minDate) {
|
||||||
|
this.minDate = this.maxDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTimeInput (value, type) {
|
||||||
|
this.timeUserInput[type] = value
|
||||||
|
if (value.length !== this.timeFormat.length) return
|
||||||
|
const parsedValue = parseDate(value, this.timeFormat)
|
||||||
|
|
||||||
|
if (parsedValue) {
|
||||||
|
if (type === 'min') {
|
||||||
|
this.minDate = modifyTime(this.minDate, parsedValue.getHours(), parsedValue.getMinutes(), parsedValue.getSeconds())
|
||||||
|
this.$nextTick(_ => this.$refs.minTimePicker.adjustSpinners())
|
||||||
|
} else {
|
||||||
|
this.maxDate = modifyTime(this.maxDate, parsedValue.getHours(), parsedValue.getMinutes(), parsedValue.getSeconds())
|
||||||
|
this.$nextTick(_ => this.$refs.maxTimePicker.adjustSpinners())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTimeChange (value, type) {
|
||||||
|
const parsedValue = parseDate(value, this.timeFormat)
|
||||||
|
if (parsedValue) {
|
||||||
|
if (type === 'min') {
|
||||||
|
this.minDate = modifyTime(this.minDate, parsedValue.getHours(), parsedValue.getMinutes(), parsedValue.getSeconds())
|
||||||
|
if (this.minDate > this.maxDate) {
|
||||||
|
this.maxDate = this.minDate
|
||||||
|
}
|
||||||
|
this.$refs.minTimePicker.value = this.minDate
|
||||||
|
this.minTimePickerVisible = false
|
||||||
|
} else {
|
||||||
|
this.maxDate = modifyTime(this.maxDate, parsedValue.getHours(), parsedValue.getMinutes(), parsedValue.getSeconds())
|
||||||
|
if (this.maxDate < this.minDate) {
|
||||||
|
this.minDate = this.maxDate
|
||||||
|
}
|
||||||
|
this.$refs.maxTimePicker.value = this.minDate
|
||||||
|
this.maxTimePickerVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleRangePick (val, close = true) {
|
||||||
|
const defaultTime = this.defaultTime || []
|
||||||
|
const minDate = modifyWithTimeString(val.minDate, defaultTime[0])
|
||||||
|
const maxDate = modifyWithTimeString(val.maxDate, defaultTime[1])
|
||||||
|
|
||||||
|
if (this.maxDate === maxDate && this.minDate === minDate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.onPick && this.onPick(val)
|
||||||
|
this.maxDate = maxDate
|
||||||
|
this.minDate = minDate
|
||||||
|
|
||||||
|
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
|
||||||
|
setTimeout(() => {
|
||||||
|
this.maxDate = maxDate
|
||||||
|
this.minDate = minDate
|
||||||
|
}, 10)
|
||||||
|
if (!close || this.showTime) return
|
||||||
|
this.handleConfirm()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleShortcutClick (shortcut) {
|
||||||
|
if (shortcut.onClick) {
|
||||||
|
shortcut.onClick(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMinTimePick (value, visible, first) {
|
||||||
|
this.minDate = this.minDate || new Date()
|
||||||
|
if (value) {
|
||||||
|
this.minDate = modifyTime(this.minDate, value.getHours(), value.getMinutes(), value.getSeconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
this.minTimePickerVisible = visible
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.maxDate || this.maxDate && this.maxDate.getTime() < this.minDate.getTime()) {
|
||||||
|
this.maxDate = new Date(this.minDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMinTimeClose () {
|
||||||
|
this.minTimePickerVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMaxTimePick (value, visible, first) {
|
||||||
|
if (this.maxDate && value) {
|
||||||
|
this.maxDate = modifyTime(this.maxDate, value.getHours(), value.getMinutes(), value.getSeconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
this.maxTimePickerVisible = visible
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.maxDate && this.minDate && this.minDate.getTime() > this.maxDate.getTime()) {
|
||||||
|
this.minDate = new Date(this.maxDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMaxTimeClose () {
|
||||||
|
this.maxTimePickerVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
// leftPrev*, rightNext* need to take care of `unlinkPanels`
|
||||||
|
leftPrevYear () {
|
||||||
|
this.leftDate = prevYear(this.leftDate)
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
leftPrevMonth () {
|
||||||
|
this.leftDate = prevMonth(this.leftDate)
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rightNextYear () {
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.leftDate = nextYear(this.leftDate)
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
} else {
|
||||||
|
this.rightDate = nextYear(this.rightDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rightNextMonth () {
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.leftDate = nextMonth(this.leftDate)
|
||||||
|
this.rightDate = nextMonth(this.leftDate)
|
||||||
|
} else {
|
||||||
|
this.rightDate = nextMonth(this.rightDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// leftNext*, rightPrev* are called when `unlinkPanels` is true
|
||||||
|
leftNextYear () {
|
||||||
|
this.leftDate = nextYear(this.leftDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
leftNextMonth () {
|
||||||
|
this.leftDate = nextMonth(this.leftDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
rightPrevYear () {
|
||||||
|
this.rightDate = prevYear(this.rightDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
rightPrevMonth () {
|
||||||
|
this.rightDate = prevMonth(this.rightDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleConfirm (visible = false) {
|
||||||
|
if (this.isValidValue([this.minDate, this.maxDate])) {
|
||||||
|
this.$emit('pick', [this.minDate, this.maxDate], visible)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (value) {
|
||||||
|
return Array.isArray(value) &&
|
||||||
|
value && value[0] && value[1] &&
|
||||||
|
isDate(value[0]) && isDate(value[1]) &&
|
||||||
|
value[0].getTime() <= value[1].getTime() && (
|
||||||
|
typeof this.disabledDate === 'function'
|
||||||
|
? !this.disabledDate(value[0]) && !this.disabledDate(value[1])
|
||||||
|
: true
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
resetView () {
|
||||||
|
// NOTE: this is a hack to reset {min, max}Date on picker open.
|
||||||
|
// TODO: correct way of doing so is to refactor {min, max}Date to be dependent on value and internal selection state
|
||||||
|
// an alternative would be resetView whenever picker becomes visible, should also investigate date-panel's resetView
|
||||||
|
if (this.minDate && this.maxDate == null) this.rangeState.selecting = false
|
||||||
|
this.minDate = this.value && isDate(this.value[0]) ? new Date(this.value[0]) : null
|
||||||
|
this.maxDate = this.value && isDate(this.value[0]) ? new Date(this.value[1]) : null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: { TimePicker, DateTable, ElInput, ElButton }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,597 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-top" @after-enter="handleEnter" @after-leave="handleLeave">
|
||||||
|
<div
|
||||||
|
v-show="visible"
|
||||||
|
class="el-picker-panel el-date-picker el-popper"
|
||||||
|
:class="[{
|
||||||
|
'has-sidebar': $slots.sidebar || shortcuts,
|
||||||
|
'has-time': showTime
|
||||||
|
}, popperClass]">
|
||||||
|
<div class="el-picker-panel__body-wrapper">
|
||||||
|
<slot name="sidebar" class="el-picker-panel__sidebar"></slot>
|
||||||
|
<div class="el-picker-panel__sidebar" v-if="shortcuts">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-picker-panel__shortcut"
|
||||||
|
v-for="(shortcut, key) in shortcuts"
|
||||||
|
:key="key"
|
||||||
|
@click="handleShortcutClick(shortcut)">{{ shortcut.text }}</button>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__body">
|
||||||
|
<div class="el-date-picker__time-header" v-if="showTime">
|
||||||
|
<span class="el-date-picker__editor-wrap">
|
||||||
|
<el-input
|
||||||
|
:placeholder="t('el.datepicker.selectDate')"
|
||||||
|
:value="visibleDate"
|
||||||
|
size="small"
|
||||||
|
@input="val => userInputDate = val"
|
||||||
|
@change="handleVisibleDateChange" />
|
||||||
|
</span>
|
||||||
|
<span class="el-date-picker__editor-wrap" v-clickoutside="handleTimePickClose">
|
||||||
|
<el-input
|
||||||
|
ref="input"
|
||||||
|
@focus="timePickerVisible = true"
|
||||||
|
:placeholder="t('el.datepicker.selectTime')"
|
||||||
|
:value="visibleTime"
|
||||||
|
size="small"
|
||||||
|
@input="val => userInputTime = val"
|
||||||
|
@change="handleVisibleTimeChange" />
|
||||||
|
<time-picker
|
||||||
|
ref="timepicker"
|
||||||
|
:time-arrow-control="arrowControl"
|
||||||
|
@pick="handleTimePick"
|
||||||
|
:visible="timePickerVisible"
|
||||||
|
@mounted="proxyTimePickerDataProperties">
|
||||||
|
</time-picker>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="el-date-picker__header"
|
||||||
|
:class="{ 'el-date-picker__header--bordered': currentView === 'year' || currentView === 'month' }"
|
||||||
|
v-show="currentView !== 'time'">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="prevYear"
|
||||||
|
:aria-label="t(`el.datepicker.prevYear`)"
|
||||||
|
class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left">
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="prevMonth"
|
||||||
|
v-show="currentView === 'date'"
|
||||||
|
:aria-label="t(`el.datepicker.prevMonth`)"
|
||||||
|
class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-arrow-left">
|
||||||
|
</button>
|
||||||
|
<span
|
||||||
|
@click="showYearPicker"
|
||||||
|
role="button"
|
||||||
|
class="el-date-picker__header-label">{{ yearLabel }}</span>
|
||||||
|
<span
|
||||||
|
@click="showMonthPicker"
|
||||||
|
v-show="currentView === 'date'"
|
||||||
|
role="button"
|
||||||
|
class="el-date-picker__header-label"
|
||||||
|
:class="{ active: currentView === 'month' }">{{t(`el.datepicker.month${ month + 1 }`)}}</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="nextYear"
|
||||||
|
:aria-label="t(`el.datepicker.nextYear`)"
|
||||||
|
class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right">
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="nextMonth"
|
||||||
|
v-show="currentView === 'date'"
|
||||||
|
:aria-label="t(`el.datepicker.nextMonth`)"
|
||||||
|
class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-arrow-right">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="el-picker-panel__content">
|
||||||
|
<date-table
|
||||||
|
v-show="currentView === 'date'"
|
||||||
|
@pick="handleDatePick"
|
||||||
|
:selection-mode="selectionMode"
|
||||||
|
:first-day-of-week="firstDayOfWeek"
|
||||||
|
:value="value"
|
||||||
|
:default-value="defaultValue ? new Date(defaultValue) : null"
|
||||||
|
:date="date"
|
||||||
|
:cell-class-name="cellClassName"
|
||||||
|
:disabled-date="disabledDate">
|
||||||
|
</date-table>
|
||||||
|
<year-table
|
||||||
|
v-show="currentView === 'year'"
|
||||||
|
@pick="handleYearPick"
|
||||||
|
:value="value"
|
||||||
|
:default-value="defaultValue ? new Date(defaultValue) : null"
|
||||||
|
:date="date"
|
||||||
|
:disabled-date="disabledDate">
|
||||||
|
</year-table>
|
||||||
|
<month-table
|
||||||
|
v-show="currentView === 'month'"
|
||||||
|
@pick="handleMonthPick"
|
||||||
|
:value="value"
|
||||||
|
:default-value="defaultValue ? new Date(defaultValue) : null"
|
||||||
|
:date="date"
|
||||||
|
:disabled-date="disabledDate">
|
||||||
|
</month-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="el-picker-panel__footer"
|
||||||
|
v-show="footerVisible && currentView === 'date'">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
class="el-picker-panel__link-btn"
|
||||||
|
@click="changeToNow"
|
||||||
|
v-show="selectionMode !== 'dates'">
|
||||||
|
{{ t('el.datepicker.now') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
plain
|
||||||
|
size="mini"
|
||||||
|
class="el-picker-panel__link-btn"
|
||||||
|
@click="confirm">
|
||||||
|
{{ t('el.datepicker.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import {
|
||||||
|
formatDate,
|
||||||
|
parseDate,
|
||||||
|
getWeekNumber,
|
||||||
|
isDate,
|
||||||
|
modifyDate,
|
||||||
|
modifyTime,
|
||||||
|
modifyWithTimeString,
|
||||||
|
clearMilliseconds,
|
||||||
|
clearTime,
|
||||||
|
prevYear,
|
||||||
|
nextYear,
|
||||||
|
prevMonth,
|
||||||
|
nextMonth,
|
||||||
|
changeYearMonthAndClampDate,
|
||||||
|
extractDateFormat,
|
||||||
|
extractTimeFormat,
|
||||||
|
timeWithinRange
|
||||||
|
} from 'element-ui/src/utils/date-util'
|
||||||
|
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import ElInput from 'element-ui/packages/input'
|
||||||
|
import ElButton from 'element-ui/packages/button'
|
||||||
|
import TimePicker from './time'
|
||||||
|
import YearTable from '../basic/year-table'
|
||||||
|
import MonthTable from '../basic/month-table'
|
||||||
|
import DateTable from '../basic/date-table'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
directives: { Clickoutside },
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
showTime (val) {
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (!val) return
|
||||||
|
this.$nextTick(_ => {
|
||||||
|
const inputElm = this.$refs.input.$el
|
||||||
|
if (inputElm) {
|
||||||
|
this.pickerWidth = inputElm.getBoundingClientRect().width + 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
value (val) {
|
||||||
|
if (this.selectionMode === 'dates' && this.value) return
|
||||||
|
if (isDate(val)) {
|
||||||
|
this.date = new Date(val)
|
||||||
|
} else {
|
||||||
|
this.date = this.getDefaultValue()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultValue (val) {
|
||||||
|
if (!isDate(this.value)) {
|
||||||
|
this.date = val ? new Date(val) : new Date()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
timePickerVisible (val) {
|
||||||
|
if (val) this.$nextTick(() => this.$refs.timepicker.adjustSpinners())
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionMode (newVal) {
|
||||||
|
if (newVal === 'month') {
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (this.currentView !== 'year' || this.currentView !== 'month') {
|
||||||
|
this.currentView = 'month'
|
||||||
|
}
|
||||||
|
} else if (newVal === 'dates') {
|
||||||
|
this.currentView = 'date'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
proxyTimePickerDataProperties () {
|
||||||
|
const format = timeFormat => { this.$refs.timepicker.format = timeFormat }
|
||||||
|
const value = value => { this.$refs.timepicker.value = value }
|
||||||
|
const date = date => { this.$refs.timepicker.date = date }
|
||||||
|
const selectableRange = selectableRange => { this.$refs.timepicker.selectableRange = selectableRange }
|
||||||
|
|
||||||
|
this.$watch('value', value)
|
||||||
|
this.$watch('date', date)
|
||||||
|
this.$watch('selectableRange', selectableRange)
|
||||||
|
|
||||||
|
format(this.timeFormat)
|
||||||
|
value(this.value)
|
||||||
|
date(this.date)
|
||||||
|
selectableRange(this.selectableRange)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClear () {
|
||||||
|
this.date = this.getDefaultValue()
|
||||||
|
this.$emit('pick', null)
|
||||||
|
},
|
||||||
|
|
||||||
|
emit (value, ...args) {
|
||||||
|
if (!value) {
|
||||||
|
this.$emit('pick', value, ...args)
|
||||||
|
} else if (Array.isArray(value)) {
|
||||||
|
const dates = value.map(date => this.showTime ? clearMilliseconds(date) : clearTime(date))
|
||||||
|
this.$emit('pick', dates, ...args)
|
||||||
|
} else {
|
||||||
|
this.$emit('pick', this.showTime ? clearMilliseconds(value) : clearTime(value), ...args)
|
||||||
|
}
|
||||||
|
this.userInputDate = null
|
||||||
|
this.userInputTime = null
|
||||||
|
},
|
||||||
|
|
||||||
|
// resetDate() {
|
||||||
|
// this.date = new Date(this.date);
|
||||||
|
// },
|
||||||
|
|
||||||
|
showMonthPicker () {
|
||||||
|
this.currentView = 'month'
|
||||||
|
},
|
||||||
|
|
||||||
|
showYearPicker () {
|
||||||
|
this.currentView = 'year'
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX: 没用到
|
||||||
|
// handleLabelClick() {
|
||||||
|
// if (this.currentView === 'date') {
|
||||||
|
// this.showMonthPicker();
|
||||||
|
// } else if (this.currentView === 'month') {
|
||||||
|
// this.showYearPicker();
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
|
prevMonth () {
|
||||||
|
this.date = prevMonth(this.date)
|
||||||
|
},
|
||||||
|
|
||||||
|
nextMonth () {
|
||||||
|
this.date = nextMonth(this.date)
|
||||||
|
},
|
||||||
|
|
||||||
|
prevYear () {
|
||||||
|
if (this.currentView === 'year') {
|
||||||
|
this.date = prevYear(this.date, 10)
|
||||||
|
} else {
|
||||||
|
this.date = prevYear(this.date)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
nextYear () {
|
||||||
|
if (this.currentView === 'year') {
|
||||||
|
this.date = nextYear(this.date, 10)
|
||||||
|
} else {
|
||||||
|
this.date = nextYear(this.date)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleShortcutClick (shortcut) {
|
||||||
|
if (shortcut.onClick) {
|
||||||
|
shortcut.onClick(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTimePick (value, visible, first) {
|
||||||
|
if (isDate(value)) {
|
||||||
|
const newDate = this.value
|
||||||
|
? modifyTime(this.value, value.getHours(), value.getMinutes(), value.getSeconds())
|
||||||
|
: modifyWithTimeString(this.getDefaultValue(), this.defaultTime)
|
||||||
|
this.date = newDate
|
||||||
|
this.emit(this.date, true)
|
||||||
|
} else {
|
||||||
|
this.emit(value, true)
|
||||||
|
}
|
||||||
|
if (!first) {
|
||||||
|
this.timePickerVisible = visible
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTimePickClose () {
|
||||||
|
this.timePickerVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMonthPick (month) {
|
||||||
|
if (this.selectionMode === 'month') {
|
||||||
|
this.date = modifyDate(this.date, this.year, month, 1)
|
||||||
|
this.emit(this.date)
|
||||||
|
} else {
|
||||||
|
this.date = changeYearMonthAndClampDate(this.date, this.year, month)
|
||||||
|
// TODO: should emit intermediate value ??
|
||||||
|
// this.emit(this.date);
|
||||||
|
this.currentView = 'date'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDatePick (value) {
|
||||||
|
if (this.selectionMode === 'day') {
|
||||||
|
let newDate = this.value
|
||||||
|
? modifyDate(this.value, value.getFullYear(), value.getMonth(), value.getDate())
|
||||||
|
: modifyWithTimeString(value, this.defaultTime)
|
||||||
|
// change default time while out of selectableRange
|
||||||
|
if (!this.checkDateWithinRange(newDate)) {
|
||||||
|
newDate = modifyDate(this.selectableRange[0][0], value.getFullYear(), value.getMonth(), value.getDate())
|
||||||
|
}
|
||||||
|
this.date = newDate
|
||||||
|
this.emit(this.date, this.showTime)
|
||||||
|
} else if (this.selectionMode === 'week') {
|
||||||
|
this.emit(value.date)
|
||||||
|
} else if (this.selectionMode === 'dates') {
|
||||||
|
this.emit(value, true) // set false to keep panel open
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleYearPick (year) {
|
||||||
|
if (this.selectionMode === 'year') {
|
||||||
|
this.date = modifyDate(this.date, year, 0, 1)
|
||||||
|
this.emit(this.date)
|
||||||
|
} else {
|
||||||
|
this.date = changeYearMonthAndClampDate(this.date, year, this.month)
|
||||||
|
// TODO: should emit intermediate value ??
|
||||||
|
// this.emit(this.date, true);
|
||||||
|
this.currentView = 'month'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
changeToNow () {
|
||||||
|
// NOTE: not a permanent solution
|
||||||
|
// consider disable "now" button in the future
|
||||||
|
if ((!this.disabledDate || !this.disabledDate(new Date())) && this.checkDateWithinRange(new Date())) {
|
||||||
|
this.date = new Date()
|
||||||
|
this.emit(this.date)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm () {
|
||||||
|
if (this.selectionMode === 'dates') {
|
||||||
|
this.emit(this.value)
|
||||||
|
} else {
|
||||||
|
// value were emitted in handle{Date,Time}Pick, nothing to update here
|
||||||
|
// deal with the scenario where: user opens the picker, then confirm without doing anything
|
||||||
|
const value = this.value
|
||||||
|
? this.value
|
||||||
|
: modifyWithTimeString(this.getDefaultValue(), this.defaultTime)
|
||||||
|
this.date = new Date(value) // refresh date
|
||||||
|
this.emit(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetView () {
|
||||||
|
if (this.selectionMode === 'month') {
|
||||||
|
this.currentView = 'month'
|
||||||
|
} else if (this.selectionMode === 'year') {
|
||||||
|
this.currentView = 'year'
|
||||||
|
} else {
|
||||||
|
this.currentView = 'date'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEnter () {
|
||||||
|
document.body.addEventListener('keydown', this.handleKeydown)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleLeave () {
|
||||||
|
this.$emit('dodestroy')
|
||||||
|
document.body.removeEventListener('keydown', this.handleKeydown)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeydown (event) {
|
||||||
|
const keyCode = event.keyCode
|
||||||
|
const list = [38, 40, 37, 39]
|
||||||
|
if (this.visible && !this.timePickerVisible) {
|
||||||
|
if (list.indexOf(keyCode) !== -1) {
|
||||||
|
this.handleKeyControl(keyCode)
|
||||||
|
event.stopPropagation()
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
if (keyCode === 13 && this.userInputDate === null && this.userInputTime === null) { // Enter
|
||||||
|
this.emit(this.date, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeyControl (keyCode) {
|
||||||
|
const mapping = {
|
||||||
|
year: {
|
||||||
|
38: -4, 40: 4, 37: -1, 39: 1, offset: (date, step) => date.setFullYear(date.getFullYear() + step)
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
38: -4, 40: 4, 37: -1, 39: 1, offset: (date, step) => date.setMonth(date.getMonth() + step)
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
38: -1, 40: 1, 37: -1, 39: 1, offset: (date, step) => date.setDate(date.getDate() + step * 7)
|
||||||
|
},
|
||||||
|
day: {
|
||||||
|
38: -7, 40: 7, 37: -1, 39: 1, offset: (date, step) => date.setDate(date.getDate() + step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const mode = this.selectionMode
|
||||||
|
const year = 3.1536e10
|
||||||
|
const now = this.date.getTime()
|
||||||
|
const newDate = new Date(this.date.getTime())
|
||||||
|
while (Math.abs(now - newDate.getTime()) <= year) {
|
||||||
|
const map = mapping[mode]
|
||||||
|
map.offset(newDate, map[keyCode])
|
||||||
|
if (typeof this.disabledDate === 'function' && this.disabledDate(newDate)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
this.date = newDate
|
||||||
|
this.$emit('pick', newDate, true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleVisibleTimeChange (value) {
|
||||||
|
const time = parseDate(value, this.timeFormat)
|
||||||
|
if (time && this.checkDateWithinRange(time)) {
|
||||||
|
this.date = modifyDate(time, this.year, this.month, this.monthDate)
|
||||||
|
this.userInputTime = null
|
||||||
|
this.$refs.timepicker.value = this.date
|
||||||
|
this.timePickerVisible = false
|
||||||
|
this.emit(this.date, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleVisibleDateChange (value) {
|
||||||
|
const date = parseDate(value, this.dateFormat)
|
||||||
|
if (date) {
|
||||||
|
if (typeof this.disabledDate === 'function' && this.disabledDate(date)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.date = modifyTime(date, this.date.getHours(), this.date.getMinutes(), this.date.getSeconds())
|
||||||
|
this.userInputDate = null
|
||||||
|
this.resetView()
|
||||||
|
this.emit(this.date, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (value) {
|
||||||
|
return value && !isNaN(value) && (
|
||||||
|
typeof this.disabledDate === 'function'
|
||||||
|
? !this.disabledDate(value)
|
||||||
|
: true
|
||||||
|
) && this.checkDateWithinRange(value)
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultValue () {
|
||||||
|
// if default-value is set, return it
|
||||||
|
// otherwise, return now (the moment this method gets called)
|
||||||
|
return this.defaultValue ? new Date(this.defaultValue) : new Date()
|
||||||
|
},
|
||||||
|
|
||||||
|
checkDateWithinRange (date) {
|
||||||
|
return this.selectableRange.length > 0
|
||||||
|
? timeWithinRange(date, this.selectableRange, this.format || 'HH:mm:ss')
|
||||||
|
: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
TimePicker, YearTable, MonthTable, DateTable, ElInput, ElButton
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
date: new Date(),
|
||||||
|
value: '',
|
||||||
|
defaultValue: null, // use getDefaultValue() for time computation
|
||||||
|
defaultTime: null,
|
||||||
|
showTime: false,
|
||||||
|
selectionMode: 'day',
|
||||||
|
shortcuts: '',
|
||||||
|
visible: false,
|
||||||
|
currentView: 'date',
|
||||||
|
disabledDate: '',
|
||||||
|
cellClassName: '',
|
||||||
|
selectableRange: [],
|
||||||
|
firstDayOfWeek: 7,
|
||||||
|
showWeekNumber: false,
|
||||||
|
timePickerVisible: false,
|
||||||
|
format: '',
|
||||||
|
arrowControl: false,
|
||||||
|
userInputDate: null,
|
||||||
|
userInputTime: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
year () {
|
||||||
|
return this.date.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
month () {
|
||||||
|
return this.date.getMonth()
|
||||||
|
},
|
||||||
|
|
||||||
|
week () {
|
||||||
|
return getWeekNumber(this.date)
|
||||||
|
},
|
||||||
|
|
||||||
|
monthDate () {
|
||||||
|
return this.date.getDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
footerVisible () {
|
||||||
|
return this.showTime || this.selectionMode === 'dates'
|
||||||
|
},
|
||||||
|
|
||||||
|
visibleTime () {
|
||||||
|
if (this.userInputTime !== null) {
|
||||||
|
return this.userInputTime
|
||||||
|
} else {
|
||||||
|
return formatDate(this.value || this.defaultValue, this.timeFormat)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
visibleDate () {
|
||||||
|
if (this.userInputDate !== null) {
|
||||||
|
return this.userInputDate
|
||||||
|
} else {
|
||||||
|
return formatDate(this.value || this.defaultValue, this.dateFormat)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
yearLabel () {
|
||||||
|
const yearTranslation = this.t('el.datepicker.year')
|
||||||
|
if (this.currentView === 'year') {
|
||||||
|
const startYear = Math.floor(this.year / 10) * 10
|
||||||
|
if (yearTranslation) {
|
||||||
|
return startYear + ' ' + yearTranslation + ' - ' + (startYear + 9) + ' ' + yearTranslation
|
||||||
|
}
|
||||||
|
return startYear + ' - ' + (startYear + 9)
|
||||||
|
}
|
||||||
|
return this.year + ' ' + yearTranslation
|
||||||
|
},
|
||||||
|
|
||||||
|
timeFormat () {
|
||||||
|
if (this.format) {
|
||||||
|
return extractTimeFormat(this.format)
|
||||||
|
} else {
|
||||||
|
return 'HH:mm:ss'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dateFormat () {
|
||||||
|
if (this.format) {
|
||||||
|
return extractDateFormat(this.format)
|
||||||
|
} else {
|
||||||
|
return 'yyyy-MM-dd'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||||
|
<div
|
||||||
|
v-show="visible"
|
||||||
|
class="el-picker-panel el-date-range-picker el-popper"
|
||||||
|
:class="[{
|
||||||
|
'has-sidebar': $slots.sidebar || shortcuts
|
||||||
|
}, popperClass]">
|
||||||
|
<div class="el-picker-panel__body-wrapper">
|
||||||
|
<slot name="sidebar" class="el-picker-panel__sidebar"></slot>
|
||||||
|
<div class="el-picker-panel__sidebar" v-if="shortcuts">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-picker-panel__shortcut"
|
||||||
|
v-for="(shortcut, key) in shortcuts"
|
||||||
|
:key="key"
|
||||||
|
@click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__body">
|
||||||
|
<div class="el-picker-panel__content el-date-range-picker__content is-left">
|
||||||
|
<div class="el-date-range-picker__header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="leftPrevYear"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
@click="leftNextYear"
|
||||||
|
:disabled="!enableYearArrow"
|
||||||
|
:class="{ 'is-disabled': !enableYearArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||||
|
<div>{{ leftLabel }}</div>
|
||||||
|
</div>
|
||||||
|
<month-table
|
||||||
|
selection-mode="range"
|
||||||
|
:date="leftDate"
|
||||||
|
:default-value="defaultValue"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
:range-state="rangeState"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
@changerange="handleChangeRange"
|
||||||
|
@pick="handleRangePick">
|
||||||
|
</month-table>
|
||||||
|
</div>
|
||||||
|
<div class="el-picker-panel__content el-date-range-picker__content is-right">
|
||||||
|
<div class="el-date-range-picker__header">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
v-if="unlinkPanels"
|
||||||
|
@click="rightPrevYear"
|
||||||
|
:disabled="!enableYearArrow"
|
||||||
|
:class="{ 'is-disabled': !enableYearArrow }"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="rightNextYear"
|
||||||
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
||||||
|
<div>{{ rightLabel }}</div>
|
||||||
|
</div>
|
||||||
|
<month-table
|
||||||
|
selection-mode="range"
|
||||||
|
:date="rightDate"
|
||||||
|
:default-value="defaultValue"
|
||||||
|
:min-date="minDate"
|
||||||
|
:max-date="maxDate"
|
||||||
|
:range-state="rangeState"
|
||||||
|
:disabled-date="disabledDate"
|
||||||
|
@changerange="handleChangeRange"
|
||||||
|
@pick="handleRangePick">
|
||||||
|
</month-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import {
|
||||||
|
isDate,
|
||||||
|
modifyWithTimeString,
|
||||||
|
prevYear,
|
||||||
|
nextYear,
|
||||||
|
nextMonth
|
||||||
|
} from 'element-ui/src/utils/date-util'
|
||||||
|
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import MonthTable from '../basic/month-table'
|
||||||
|
import ElInput from 'element-ui/packages/input'
|
||||||
|
import ElButton from 'element-ui/packages/button'
|
||||||
|
|
||||||
|
const calcDefaultValue = (defaultValue) => {
|
||||||
|
if (Array.isArray(defaultValue)) {
|
||||||
|
return [new Date(defaultValue[0]), new Date(defaultValue[1])]
|
||||||
|
} else if (defaultValue) {
|
||||||
|
return [new Date(defaultValue), nextMonth(new Date(defaultValue))]
|
||||||
|
} else {
|
||||||
|
return [new Date(), nextMonth(new Date())]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
directives: { Clickoutside },
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
btnDisabled () {
|
||||||
|
return !(this.minDate && this.maxDate && !this.selecting && this.isValidValue([this.minDate, this.maxDate]))
|
||||||
|
},
|
||||||
|
|
||||||
|
leftLabel () {
|
||||||
|
return this.leftDate.getFullYear() + ' ' + this.t('el.datepicker.year')
|
||||||
|
},
|
||||||
|
|
||||||
|
rightLabel () {
|
||||||
|
return this.rightDate.getFullYear() + ' ' + this.t('el.datepicker.year')
|
||||||
|
},
|
||||||
|
|
||||||
|
leftYear () {
|
||||||
|
return this.leftDate.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
rightYear () {
|
||||||
|
return this.rightDate.getFullYear() === this.leftDate.getFullYear() ? this.leftDate.getFullYear() + 1 : this.rightDate.getFullYear()
|
||||||
|
},
|
||||||
|
|
||||||
|
enableYearArrow () {
|
||||||
|
return this.unlinkPanels && this.rightYear > this.leftYear + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
value: [],
|
||||||
|
defaultValue: null,
|
||||||
|
defaultTime: null,
|
||||||
|
minDate: '',
|
||||||
|
maxDate: '',
|
||||||
|
leftDate: new Date(),
|
||||||
|
rightDate: nextYear(new Date()),
|
||||||
|
rangeState: {
|
||||||
|
endDate: null,
|
||||||
|
selecting: false,
|
||||||
|
row: null,
|
||||||
|
column: null
|
||||||
|
},
|
||||||
|
shortcuts: '',
|
||||||
|
visible: '',
|
||||||
|
disabledDate: '',
|
||||||
|
format: '',
|
||||||
|
arrowControl: false,
|
||||||
|
unlinkPanels: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
value (newVal) {
|
||||||
|
if (!newVal) {
|
||||||
|
this.minDate = null
|
||||||
|
this.maxDate = null
|
||||||
|
} else if (Array.isArray(newVal)) {
|
||||||
|
this.minDate = isDate(newVal[0]) ? new Date(newVal[0]) : null
|
||||||
|
this.maxDate = isDate(newVal[1]) ? new Date(newVal[1]) : null
|
||||||
|
if (this.minDate) {
|
||||||
|
this.leftDate = this.minDate
|
||||||
|
if (this.unlinkPanels && this.maxDate) {
|
||||||
|
const minDateYear = this.minDate.getFullYear()
|
||||||
|
const maxDateYear = this.maxDate.getFullYear()
|
||||||
|
this.rightDate = minDateYear === maxDateYear
|
||||||
|
? nextYear(this.maxDate)
|
||||||
|
: this.maxDate
|
||||||
|
} else {
|
||||||
|
this.rightDate = nextYear(this.leftDate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.leftDate = calcDefaultValue(this.defaultValue)[0]
|
||||||
|
this.rightDate = nextYear(this.leftDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultValue (val) {
|
||||||
|
if (!Array.isArray(this.value)) {
|
||||||
|
const [left, right] = calcDefaultValue(val)
|
||||||
|
this.leftDate = left
|
||||||
|
this.rightDate = val && val[1] && left.getFullYear() !== right.getFullYear() && this.unlinkPanels
|
||||||
|
? right
|
||||||
|
: nextYear(this.leftDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleClear () {
|
||||||
|
this.minDate = null
|
||||||
|
this.maxDate = null
|
||||||
|
this.leftDate = calcDefaultValue(this.defaultValue)[0]
|
||||||
|
this.rightDate = nextYear(this.leftDate)
|
||||||
|
this.$emit('pick', null)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChangeRange (val) {
|
||||||
|
this.minDate = val.minDate
|
||||||
|
this.maxDate = val.maxDate
|
||||||
|
this.rangeState = val.rangeState
|
||||||
|
},
|
||||||
|
|
||||||
|
handleRangePick (val, close = true) {
|
||||||
|
const defaultTime = this.defaultTime || []
|
||||||
|
const minDate = modifyWithTimeString(val.minDate, defaultTime[0])
|
||||||
|
const maxDate = modifyWithTimeString(val.maxDate, defaultTime[1])
|
||||||
|
if (this.maxDate === maxDate && this.minDate === minDate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.onPick && this.onPick(val)
|
||||||
|
this.maxDate = maxDate
|
||||||
|
this.minDate = minDate
|
||||||
|
|
||||||
|
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
|
||||||
|
setTimeout(() => {
|
||||||
|
this.maxDate = maxDate
|
||||||
|
this.minDate = minDate
|
||||||
|
}, 10)
|
||||||
|
if (!close) return
|
||||||
|
this.handleConfirm()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleShortcutClick (shortcut) {
|
||||||
|
if (shortcut.onClick) {
|
||||||
|
shortcut.onClick(this)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// leftPrev*, rightNext* need to take care of `unlinkPanels`
|
||||||
|
leftPrevYear () {
|
||||||
|
this.leftDate = prevYear(this.leftDate)
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.rightDate = prevYear(this.rightDate)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rightNextYear () {
|
||||||
|
if (!this.unlinkPanels) {
|
||||||
|
this.leftDate = nextYear(this.leftDate)
|
||||||
|
}
|
||||||
|
this.rightDate = nextYear(this.rightDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
// leftNext*, rightPrev* are called when `unlinkPanels` is true
|
||||||
|
leftNextYear () {
|
||||||
|
this.leftDate = nextYear(this.leftDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
rightPrevYear () {
|
||||||
|
this.rightDate = prevYear(this.rightDate)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleConfirm (visible = false) {
|
||||||
|
if (this.isValidValue([this.minDate, this.maxDate])) {
|
||||||
|
this.$emit('pick', [this.minDate, this.maxDate], visible)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (value) {
|
||||||
|
return Array.isArray(value) &&
|
||||||
|
value && value[0] && value[1] &&
|
||||||
|
isDate(value[0]) && isDate(value[1]) &&
|
||||||
|
value[0].getTime() <= value[1].getTime() && (
|
||||||
|
typeof this.disabledDate === 'function'
|
||||||
|
? !this.disabledDate(value[0]) && !this.disabledDate(value[1])
|
||||||
|
: true
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
resetView () {
|
||||||
|
// NOTE: this is a hack to reset {min, max}Date on picker open.
|
||||||
|
// TODO: correct way of doing so is to refactor {min, max}Date to be dependent on value and internal selection state
|
||||||
|
// an alternative would be resetView whenever picker becomes visible, should also investigate date-panel's resetView
|
||||||
|
this.minDate = this.value && isDate(this.value[0]) ? new Date(this.value[0]) : null
|
||||||
|
this.maxDate = this.value && isDate(this.value[0]) ? new Date(this.value[1]) : null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: { MonthTable, ElInput, ElButton }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
<template>
|
||||||
|
<transition
|
||||||
|
name="el-zoom-in-top"
|
||||||
|
@after-leave="$emit('dodestroy')">
|
||||||
|
<div
|
||||||
|
v-show="visible"
|
||||||
|
class="el-time-range-picker el-picker-panel el-popper"
|
||||||
|
:class="popperClass">
|
||||||
|
<div class="el-time-range-picker__content">
|
||||||
|
<div class="el-time-range-picker__cell">
|
||||||
|
<div class="el-time-range-picker__header">{{ t('el.datepicker.startTime') }}</div>
|
||||||
|
<div
|
||||||
|
:class="{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
|
||||||
|
class="el-time-range-picker__body el-time-panel__content">
|
||||||
|
<time-spinner
|
||||||
|
ref="minSpinner"
|
||||||
|
:show-seconds="showSeconds"
|
||||||
|
:am-pm-mode="amPmMode"
|
||||||
|
@change="handleMinChange"
|
||||||
|
:arrow-control="arrowControl"
|
||||||
|
@select-range="setMinSelectionRange"
|
||||||
|
:date="minDate">
|
||||||
|
</time-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="el-time-range-picker__cell">
|
||||||
|
<div class="el-time-range-picker__header">{{ t('el.datepicker.endTime') }}</div>
|
||||||
|
<div
|
||||||
|
:class="{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
|
||||||
|
class="el-time-range-picker__body el-time-panel__content">
|
||||||
|
<time-spinner
|
||||||
|
ref="maxSpinner"
|
||||||
|
:show-seconds="showSeconds"
|
||||||
|
:am-pm-mode="amPmMode"
|
||||||
|
@change="handleMaxChange"
|
||||||
|
:arrow-control="arrowControl"
|
||||||
|
@select-range="setMaxSelectionRange"
|
||||||
|
:date="maxDate">
|
||||||
|
</time-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="el-time-panel__footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-time-panel__btn cancel"
|
||||||
|
@click="handleCancel()">{{ t('el.datepicker.cancel') }}</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-time-panel__btn confirm"
|
||||||
|
@click="handleConfirm()"
|
||||||
|
:disabled="btnDisabled">{{ t('el.datepicker.confirm') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import {
|
||||||
|
parseDate,
|
||||||
|
limitTimeRange,
|
||||||
|
modifyDate,
|
||||||
|
clearMilliseconds,
|
||||||
|
timeWithinRange
|
||||||
|
} from 'element-ui/src/utils/date-util'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import TimeSpinner from '../basic/time-spinner'
|
||||||
|
|
||||||
|
const MIN_TIME = parseDate('00:00:00', 'HH:mm:ss')
|
||||||
|
const MAX_TIME = parseDate('23:59:59', 'HH:mm:ss')
|
||||||
|
|
||||||
|
const minTimeOfDay = function (date) {
|
||||||
|
return modifyDate(MIN_TIME, date.getFullYear(), date.getMonth(), date.getDate())
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxTimeOfDay = function (date) {
|
||||||
|
return modifyDate(MAX_TIME, date.getFullYear(), date.getMonth(), date.getDate())
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase time by amount of milliseconds, but within the range of day
|
||||||
|
const advanceTime = function (date, amount) {
|
||||||
|
return new Date(Math.min(date.getTime() + amount, maxTimeOfDay(date).getTime()))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
components: { TimeSpinner },
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
showSeconds () {
|
||||||
|
return (this.format || '').indexOf('ss') !== -1
|
||||||
|
},
|
||||||
|
|
||||||
|
offset () {
|
||||||
|
return this.showSeconds ? 11 : 8
|
||||||
|
},
|
||||||
|
|
||||||
|
spinner () {
|
||||||
|
return this.selectionRange[0] < this.offset ? this.$refs.minSpinner : this.$refs.maxSpinner
|
||||||
|
},
|
||||||
|
|
||||||
|
btnDisabled () {
|
||||||
|
return this.minDate.getTime() > this.maxDate.getTime()
|
||||||
|
},
|
||||||
|
amPmMode () {
|
||||||
|
if ((this.format || '').indexOf('A') !== -1) return 'A'
|
||||||
|
if ((this.format || '').indexOf('a') !== -1) return 'a'
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
minDate: new Date(),
|
||||||
|
maxDate: new Date(),
|
||||||
|
value: [],
|
||||||
|
oldValue: [new Date(), new Date()],
|
||||||
|
defaultValue: null,
|
||||||
|
format: 'HH:mm:ss',
|
||||||
|
visible: false,
|
||||||
|
selectionRange: [0, 2],
|
||||||
|
arrowControl: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
value (value) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
this.minDate = new Date(value[0])
|
||||||
|
this.maxDate = new Date(value[1])
|
||||||
|
} else {
|
||||||
|
if (Array.isArray(this.defaultValue)) {
|
||||||
|
this.minDate = new Date(this.defaultValue[0])
|
||||||
|
this.maxDate = new Date(this.defaultValue[1])
|
||||||
|
} else if (this.defaultValue) {
|
||||||
|
this.minDate = new Date(this.defaultValue)
|
||||||
|
this.maxDate = advanceTime(new Date(this.defaultValue), 60 * 60 * 1000)
|
||||||
|
} else {
|
||||||
|
this.minDate = new Date()
|
||||||
|
this.maxDate = advanceTime(new Date(), 60 * 60 * 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
visible (val) {
|
||||||
|
if (val) {
|
||||||
|
this.oldValue = this.value
|
||||||
|
this.$nextTick(() => this.$refs.minSpinner.emitSelectRange('hours'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleClear () {
|
||||||
|
this.$emit('pick', null)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCancel () {
|
||||||
|
this.$emit('pick', this.oldValue)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMinChange (date) {
|
||||||
|
this.minDate = clearMilliseconds(date)
|
||||||
|
this.handleChange()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMaxChange (date) {
|
||||||
|
this.maxDate = clearMilliseconds(date)
|
||||||
|
this.handleChange()
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange () {
|
||||||
|
if (this.isValidValue([this.minDate, this.maxDate])) {
|
||||||
|
this.$refs.minSpinner.selectableRange = [[minTimeOfDay(this.minDate), this.maxDate]]
|
||||||
|
this.$refs.maxSpinner.selectableRange = [[this.minDate, maxTimeOfDay(this.maxDate)]]
|
||||||
|
this.$emit('pick', [this.minDate, this.maxDate], true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setMinSelectionRange (start, end) {
|
||||||
|
this.$emit('select-range', start, end, 'min')
|
||||||
|
this.selectionRange = [start, end]
|
||||||
|
},
|
||||||
|
|
||||||
|
setMaxSelectionRange (start, end) {
|
||||||
|
this.$emit('select-range', start, end, 'max')
|
||||||
|
this.selectionRange = [start + this.offset, end + this.offset]
|
||||||
|
},
|
||||||
|
|
||||||
|
handleConfirm (visible = false) {
|
||||||
|
const minSelectableRange = this.$refs.minSpinner.selectableRange
|
||||||
|
const maxSelectableRange = this.$refs.maxSpinner.selectableRange
|
||||||
|
|
||||||
|
this.minDate = limitTimeRange(this.minDate, minSelectableRange, this.format)
|
||||||
|
this.maxDate = limitTimeRange(this.maxDate, maxSelectableRange, this.format)
|
||||||
|
|
||||||
|
this.$emit('pick', [this.minDate, this.maxDate], visible)
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustSpinners () {
|
||||||
|
this.$refs.minSpinner.adjustSpinners()
|
||||||
|
this.$refs.maxSpinner.adjustSpinners()
|
||||||
|
},
|
||||||
|
|
||||||
|
changeSelectionRange (step) {
|
||||||
|
const list = this.showSeconds ? [0, 3, 6, 11, 14, 17] : [0, 3, 8, 11]
|
||||||
|
const mapping = ['hours', 'minutes'].concat(this.showSeconds ? ['seconds'] : [])
|
||||||
|
const index = list.indexOf(this.selectionRange[0])
|
||||||
|
const next = (index + step + list.length) % list.length
|
||||||
|
const half = list.length / 2
|
||||||
|
if (next < half) {
|
||||||
|
this.$refs.minSpinner.emitSelectRange(mapping[next])
|
||||||
|
} else {
|
||||||
|
this.$refs.maxSpinner.emitSelectRange(mapping[next - half])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (date) {
|
||||||
|
return Array.isArray(date) &&
|
||||||
|
timeWithinRange(this.minDate, this.$refs.minSpinner.selectableRange) &&
|
||||||
|
timeWithinRange(this.maxDate, this.$refs.maxSpinner.selectableRange)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeydown (event) {
|
||||||
|
const keyCode = event.keyCode
|
||||||
|
const mapping = { 38: -1, 40: 1, 37: -1, 39: 1 }
|
||||||
|
|
||||||
|
// Left or Right
|
||||||
|
if (keyCode === 37 || keyCode === 39) {
|
||||||
|
const step = mapping[keyCode]
|
||||||
|
this.changeSelectionRange(step)
|
||||||
|
event.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Up or Down
|
||||||
|
if (keyCode === 38 || keyCode === 40) {
|
||||||
|
const step = mapping[keyCode]
|
||||||
|
this.spinner.scrollDown(step)
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-top" @before-enter="handleMenuEnter" @after-leave="$emit('dodestroy')">
|
||||||
|
<div
|
||||||
|
ref="popper"
|
||||||
|
v-show="visible"
|
||||||
|
:style="{ width: width + 'px' }"
|
||||||
|
:class="popperClass"
|
||||||
|
class="el-picker-panel time-select el-popper">
|
||||||
|
<el-scrollbar noresize wrap-class="el-picker-panel__content">
|
||||||
|
<div class="time-select-item"
|
||||||
|
v-for="item in items"
|
||||||
|
:class="{ selected: value === item.value, disabled: item.disabled, default: item.value === defaultValue }"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
:key="item.value"
|
||||||
|
@click="handleClick(item)">{{ item.value }}</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import ElScrollbar from 'element-ui/packages/scrollbar'
|
||||||
|
import scrollIntoView from 'element-ui/src/utils/scroll-into-view'
|
||||||
|
|
||||||
|
const parseTime = function (time) {
|
||||||
|
const values = (time || '').split(':')
|
||||||
|
if (values.length >= 2) {
|
||||||
|
const hours = parseInt(values[0], 10)
|
||||||
|
const minutes = parseInt(values[1], 10)
|
||||||
|
|
||||||
|
return {
|
||||||
|
hours,
|
||||||
|
minutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* istanbul ignore next */
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const compareTime = function (time1, time2) {
|
||||||
|
const value1 = parseTime(time1)
|
||||||
|
const value2 = parseTime(time2)
|
||||||
|
|
||||||
|
const minutes1 = value1.minutes + value1.hours * 60
|
||||||
|
const minutes2 = value2.minutes + value2.hours * 60
|
||||||
|
|
||||||
|
if (minutes1 === minutes2) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return minutes1 > minutes2 ? 1 : -1
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatTime = function (time) {
|
||||||
|
return (time.hours < 10 ? '0' + time.hours : time.hours) + ':' + (time.minutes < 10 ? '0' + time.minutes : time.minutes)
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextTime = function (time, step) {
|
||||||
|
const timeValue = parseTime(time)
|
||||||
|
const stepValue = parseTime(step)
|
||||||
|
|
||||||
|
const next = {
|
||||||
|
hours: timeValue.hours,
|
||||||
|
minutes: timeValue.minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
next.minutes += stepValue.minutes
|
||||||
|
next.hours += stepValue.hours
|
||||||
|
|
||||||
|
next.hours += Math.floor(next.minutes / 60)
|
||||||
|
next.minutes = next.minutes % 60
|
||||||
|
|
||||||
|
return formatTime(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { ElScrollbar },
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
value (val) {
|
||||||
|
if (!val) return
|
||||||
|
this.$nextTick(() => this.scrollToOption())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleClick (item) {
|
||||||
|
if (!item.disabled) {
|
||||||
|
this.$emit('pick', item.value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClear () {
|
||||||
|
this.$emit('pick', null)
|
||||||
|
},
|
||||||
|
|
||||||
|
scrollToOption (selector = '.selected') {
|
||||||
|
const menu = this.$refs.popper.querySelector('.el-picker-panel__content')
|
||||||
|
scrollIntoView(menu, menu.querySelector(selector))
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMenuEnter () {
|
||||||
|
const selected = this.items.map(item => item.value).indexOf(this.value) !== -1
|
||||||
|
const hasDefault = this.items.map(item => item.value).indexOf(this.defaultValue) !== -1
|
||||||
|
const option = (selected && '.selected') || (hasDefault && '.default') || '.time-select-item:not(.disabled)'
|
||||||
|
this.$nextTick(() => this.scrollToOption(option))
|
||||||
|
},
|
||||||
|
|
||||||
|
scrollDown (step) {
|
||||||
|
const items = this.items
|
||||||
|
const length = items.length
|
||||||
|
let total = items.length
|
||||||
|
let index = items.map(item => item.value).indexOf(this.value)
|
||||||
|
while (total--) {
|
||||||
|
index = (index + step + length) % length
|
||||||
|
if (!items[index].disabled) {
|
||||||
|
this.$emit('pick', items[index].value, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (date) {
|
||||||
|
return this.items.filter(item => !item.disabled).map(item => item.value).indexOf(date) !== -1
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeydown (event) {
|
||||||
|
const keyCode = event.keyCode
|
||||||
|
if (keyCode === 38 || keyCode === 40) {
|
||||||
|
const mapping = { 40: 1, 38: -1 }
|
||||||
|
const offset = mapping[keyCode.toString()]
|
||||||
|
this.scrollDown(offset)
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
start: '09:00',
|
||||||
|
end: '18:00',
|
||||||
|
step: '00:30',
|
||||||
|
value: '',
|
||||||
|
defaultValue: '',
|
||||||
|
visible: false,
|
||||||
|
minTime: '',
|
||||||
|
maxTime: '',
|
||||||
|
width: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
items () {
|
||||||
|
const start = this.start
|
||||||
|
const end = this.end
|
||||||
|
const step = this.step
|
||||||
|
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
if (start && end && step) {
|
||||||
|
let current = start
|
||||||
|
while (compareTime(current, end) <= 0) {
|
||||||
|
result.push({
|
||||||
|
value: current,
|
||||||
|
disabled: compareTime(current, this.minTime || '-1:-1') <= 0 ||
|
||||||
|
compareTime(current, this.maxTime || '100:100') >= 0
|
||||||
|
})
|
||||||
|
current = nextTime(current, step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-top" @after-leave="$emit('dodestroy')">
|
||||||
|
<div
|
||||||
|
v-show="visible"
|
||||||
|
class="el-time-panel el-popper"
|
||||||
|
:class="popperClass">
|
||||||
|
<div class="el-time-panel__content" :class="{ 'has-seconds': showSeconds }">
|
||||||
|
<time-spinner
|
||||||
|
ref="spinner"
|
||||||
|
@change="handleChange"
|
||||||
|
:arrow-control="useArrow"
|
||||||
|
:show-seconds="showSeconds"
|
||||||
|
:am-pm-mode="amPmMode"
|
||||||
|
@select-range="setSelectionRange"
|
||||||
|
:date="date">
|
||||||
|
</time-spinner>
|
||||||
|
</div>
|
||||||
|
<div class="el-time-panel__footer">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-time-panel__btn cancel"
|
||||||
|
@click="handleCancel">{{ t('el.datepicker.cancel') }}</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="el-time-panel__btn"
|
||||||
|
:class="{confirm: !disabled}"
|
||||||
|
@click="handleConfirm()">{{ t('el.datepicker.confirm') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import { limitTimeRange, isDate, clearMilliseconds, timeWithinRange } from 'element-ui/src/utils/date-util'
|
||||||
|
import Locale from 'element-ui/src/mixins/locale'
|
||||||
|
import TimeSpinner from '../basic/time-spinner'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Locale],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
TimeSpinner
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
visible: Boolean,
|
||||||
|
timeArrowControl: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
visible (val) {
|
||||||
|
if (val) {
|
||||||
|
this.oldValue = this.value
|
||||||
|
this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'))
|
||||||
|
} else {
|
||||||
|
this.needInitAdjust = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
value (newVal) {
|
||||||
|
let date
|
||||||
|
if (newVal instanceof Date) {
|
||||||
|
date = limitTimeRange(newVal, this.selectableRange, this.format)
|
||||||
|
} else if (!newVal) {
|
||||||
|
date = this.defaultValue ? new Date(this.defaultValue) : new Date()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.date = date
|
||||||
|
if (this.visible && this.needInitAdjust) {
|
||||||
|
this.$nextTick(_ => this.adjustSpinners())
|
||||||
|
this.needInitAdjust = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectableRange (val) {
|
||||||
|
this.$refs.spinner.selectableRange = val
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultValue (val) {
|
||||||
|
if (!isDate(this.value)) {
|
||||||
|
this.date = val ? new Date(val) : new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
popperClass: '',
|
||||||
|
format: 'HH:mm:ss',
|
||||||
|
value: '',
|
||||||
|
defaultValue: null,
|
||||||
|
date: new Date(),
|
||||||
|
oldValue: new Date(),
|
||||||
|
selectableRange: [],
|
||||||
|
selectionRange: [0, 2],
|
||||||
|
disabled: false,
|
||||||
|
arrowControl: false,
|
||||||
|
needInitAdjust: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
showSeconds () {
|
||||||
|
return (this.format || '').indexOf('ss') !== -1
|
||||||
|
},
|
||||||
|
useArrow () {
|
||||||
|
return this.arrowControl || this.timeArrowControl || false
|
||||||
|
},
|
||||||
|
amPmMode () {
|
||||||
|
if ((this.format || '').indexOf('A') !== -1) return 'A'
|
||||||
|
if ((this.format || '').indexOf('a') !== -1) return 'a'
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
handleCancel () {
|
||||||
|
this.$emit('pick', this.oldValue, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange (date) {
|
||||||
|
// this.visible avoids edge cases, when use scrolls during panel closing animation
|
||||||
|
if (this.visible) {
|
||||||
|
this.date = clearMilliseconds(date)
|
||||||
|
// if date is out of range, do not emit
|
||||||
|
if (this.isValidValue(this.date)) {
|
||||||
|
this.$emit('pick', this.date, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setSelectionRange (start, end) {
|
||||||
|
this.$emit('select-range', start, end)
|
||||||
|
this.selectionRange = [start, end]
|
||||||
|
},
|
||||||
|
|
||||||
|
handleConfirm (visible = false, first) {
|
||||||
|
if (first) return
|
||||||
|
const date = clearMilliseconds(limitTimeRange(this.date, this.selectableRange, this.format))
|
||||||
|
this.$emit('pick', date, visible, first)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeydown (event) {
|
||||||
|
const keyCode = event.keyCode
|
||||||
|
const mapping = { 38: -1, 40: 1, 37: -1, 39: 1 }
|
||||||
|
|
||||||
|
// Left or Right
|
||||||
|
if (keyCode === 37 || keyCode === 39) {
|
||||||
|
const step = mapping[keyCode]
|
||||||
|
this.changeSelectionRange(step)
|
||||||
|
event.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Up or Down
|
||||||
|
if (keyCode === 38 || keyCode === 40) {
|
||||||
|
const step = mapping[keyCode]
|
||||||
|
this.$refs.spinner.scrollDown(step)
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (date) {
|
||||||
|
return timeWithinRange(date, this.selectableRange, this.format)
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustSpinners () {
|
||||||
|
return this.$refs.spinner.adjustSpinners()
|
||||||
|
},
|
||||||
|
|
||||||
|
changeSelectionRange (step) {
|
||||||
|
const list = [0, 3].concat(this.showSeconds ? [6] : [])
|
||||||
|
const mapping = ['hours', 'minutes'].concat(this.showSeconds ? ['seconds'] : [])
|
||||||
|
const index = list.indexOf(this.selectionRange[0])
|
||||||
|
const next = (index + step + list.length) % list.length
|
||||||
|
this.$refs.spinner.emitSelectRange(mapping[next])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.$nextTick(() => this.handleConfirm(true, true))
|
||||||
|
this.$emit('mounted')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
929
nezha-fronted/src/components/common/myDatePicker/src/picker.vue
Normal file
929
nezha-fronted/src/components/common/myDatePicker/src/picker.vue
Normal file
@@ -0,0 +1,929 @@
|
|||||||
|
<template>
|
||||||
|
<el-input
|
||||||
|
class="el-date-editor"
|
||||||
|
:class="'el-date-editor--' + type"
|
||||||
|
:readonly="!editable || readonly || type === 'dates' || type === 'week'"
|
||||||
|
:disabled="pickerDisabled"
|
||||||
|
:size="pickerSize"
|
||||||
|
:name="name"
|
||||||
|
v-bind="firstInputId"
|
||||||
|
v-if="!ranged"
|
||||||
|
v-clickoutside="handleClose"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@keydown.native="handleKeydown"
|
||||||
|
:value="displayValue"
|
||||||
|
@input="value => userInput = value"
|
||||||
|
@change="handleChange"
|
||||||
|
@mouseenter.native="handleMouseEnter"
|
||||||
|
@mouseleave.native="showClose = false"
|
||||||
|
:validateEvent="false"
|
||||||
|
ref="reference">
|
||||||
|
<i slot="prefix"
|
||||||
|
class="el-input__icon"
|
||||||
|
:class="triggerClass"
|
||||||
|
@click="handleFocus">
|
||||||
|
</i>
|
||||||
|
<i slot="suffix"
|
||||||
|
class="el-input__icon"
|
||||||
|
@click="handleClickIcon"
|
||||||
|
:class="[showClose ? '' + clearIcon : '']"
|
||||||
|
v-if="haveTrigger">
|
||||||
|
</i>
|
||||||
|
</el-input>
|
||||||
|
<div
|
||||||
|
class="el-date-editor el-range-editor el-input__inner"
|
||||||
|
:class="[
|
||||||
|
'el-date-editor--' + type,
|
||||||
|
pickerSize ? `el-range-editor--${ pickerSize }` : '',
|
||||||
|
pickerDisabled ? 'is-disabled' : '',
|
||||||
|
pickerVisible ? 'is-active' : ''
|
||||||
|
]"
|
||||||
|
@click="handleRangeClick"
|
||||||
|
@mouseenter="handleMouseEnter"
|
||||||
|
@mouseleave="showClose = false"
|
||||||
|
@keydown="handleKeydown"
|
||||||
|
ref="reference"
|
||||||
|
v-clickoutside="handleClose"
|
||||||
|
v-else>
|
||||||
|
<i :class="['el-input__icon', 'el-range__icon', triggerClass]"></i>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
:placeholder="startPlaceholder"
|
||||||
|
:value="displayValue && displayValue[0]"
|
||||||
|
:disabled="pickerDisabled"
|
||||||
|
v-bind="firstInputId"
|
||||||
|
:readonly="!editable || readonly"
|
||||||
|
:name="name && name[0]"
|
||||||
|
@input="handleStartInput"
|
||||||
|
@change="handleStartChange"
|
||||||
|
@focus="handleFocus"
|
||||||
|
class="el-range-input">
|
||||||
|
<slot name="range-separator">
|
||||||
|
<span class="el-range-separator">{{ rangeSeparator }}</span>
|
||||||
|
</slot>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
:placeholder="endPlaceholder"
|
||||||
|
:value="displayValue && displayValue[1]"
|
||||||
|
:disabled="pickerDisabled"
|
||||||
|
v-bind="secondInputId"
|
||||||
|
:readonly="!editable || readonly"
|
||||||
|
:name="name && name[1]"
|
||||||
|
@input="handleEndInput"
|
||||||
|
@change="handleEndChange"
|
||||||
|
@focus="handleFocus"
|
||||||
|
class="el-range-input">
|
||||||
|
<i
|
||||||
|
@click="handleClickIcon"
|
||||||
|
v-if="haveTrigger"
|
||||||
|
:class="[showClose ? '' + clearIcon : '']"
|
||||||
|
class="el-input__icon el-range__close-icon">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Clickoutside from 'element-ui/src/utils/clickoutside'
|
||||||
|
import { formatDate, parseDate, isDateObject, getWeekNumber } from 'element-ui/src/utils/date-util'
|
||||||
|
import Popper from 'element-ui/src/utils/vue-popper'
|
||||||
|
import Emitter from 'element-ui/src/mixins/emitter'
|
||||||
|
import ElInput from 'element-ui/packages/input'
|
||||||
|
import merge from 'element-ui/src/utils/merge'
|
||||||
|
|
||||||
|
const NewPopper = {
|
||||||
|
props: {
|
||||||
|
appendToBody: Popper.props.appendToBody,
|
||||||
|
offset: Popper.props.offset,
|
||||||
|
boundariesPadding: Popper.props.boundariesPadding,
|
||||||
|
arrowOffset: Popper.props.arrowOffset
|
||||||
|
},
|
||||||
|
methods: Popper.methods,
|
||||||
|
data () {
|
||||||
|
return merge({ visibleArrow: true }, Popper.data)
|
||||||
|
},
|
||||||
|
beforeDestroy: Popper.beforeDestroy
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_FORMATS = {
|
||||||
|
date: 'yyyy-MM-dd',
|
||||||
|
month: 'yyyy-MM',
|
||||||
|
datetime: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
time: 'HH:mm:ss',
|
||||||
|
week: 'yyyywWW',
|
||||||
|
timerange: 'HH:mm:ss',
|
||||||
|
daterange: 'yyyy-MM-dd',
|
||||||
|
monthrange: 'yyyy-MM',
|
||||||
|
datetimerange: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
year: 'yyyy'
|
||||||
|
}
|
||||||
|
const HAVE_TRIGGER_TYPES = [
|
||||||
|
'date',
|
||||||
|
'datetime',
|
||||||
|
'time',
|
||||||
|
'time-select',
|
||||||
|
'week',
|
||||||
|
'month',
|
||||||
|
'year',
|
||||||
|
'daterange',
|
||||||
|
'monthrange',
|
||||||
|
'timerange',
|
||||||
|
'datetimerange',
|
||||||
|
'dates'
|
||||||
|
]
|
||||||
|
const DATE_FORMATTER = function (value, format) {
|
||||||
|
if (format === 'timestamp') return value.getTime()
|
||||||
|
return formatDate(value, format)
|
||||||
|
}
|
||||||
|
const DATE_PARSER = function (text, format) {
|
||||||
|
if (format === 'timestamp') return new Date(Number(text))
|
||||||
|
return parseDate(text, format)
|
||||||
|
}
|
||||||
|
const RANGE_FORMATTER = function (value, format) {
|
||||||
|
if (Array.isArray(value) && value.length === 2) {
|
||||||
|
const start = value[0]
|
||||||
|
const end = value[1]
|
||||||
|
|
||||||
|
if (start && end) {
|
||||||
|
return [DATE_FORMATTER(start, format), DATE_FORMATTER(end, format)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const RANGE_PARSER = function (array, format, separator) {
|
||||||
|
if (!Array.isArray(array)) {
|
||||||
|
array = array.split(separator)
|
||||||
|
}
|
||||||
|
if (array.length === 2) {
|
||||||
|
const range1 = array[0]
|
||||||
|
const range2 = array[1]
|
||||||
|
|
||||||
|
return [DATE_PARSER(range1, format), DATE_PARSER(range2, format)]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const TYPE_VALUE_RESOLVER_MAP = {
|
||||||
|
default: {
|
||||||
|
formatter (value) {
|
||||||
|
if (!value) return ''
|
||||||
|
return '' + value
|
||||||
|
},
|
||||||
|
parser (text) {
|
||||||
|
if (text === undefined || text === '') return null
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
formatter (value, format) {
|
||||||
|
const week = getWeekNumber(value)
|
||||||
|
const month = value.getMonth()
|
||||||
|
const trueDate = new Date(value)
|
||||||
|
if (week === 1 && month === 11) {
|
||||||
|
trueDate.setHours(0, 0, 0, 0)
|
||||||
|
trueDate.setDate(trueDate.getDate() + 3 - (trueDate.getDay() + 6) % 7)
|
||||||
|
}
|
||||||
|
let date = formatDate(trueDate, format)
|
||||||
|
|
||||||
|
date = /WW/.test(date)
|
||||||
|
? date.replace(/WW/, week < 10 ? '0' + week : week)
|
||||||
|
: date.replace(/W/, week)
|
||||||
|
return date
|
||||||
|
},
|
||||||
|
parser (text, format) {
|
||||||
|
// parse as if a normal date
|
||||||
|
return TYPE_VALUE_RESOLVER_MAP.date.parser(text, format)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
formatter: DATE_FORMATTER,
|
||||||
|
parser: DATE_PARSER
|
||||||
|
},
|
||||||
|
datetime: {
|
||||||
|
formatter: DATE_FORMATTER,
|
||||||
|
parser: DATE_PARSER
|
||||||
|
},
|
||||||
|
daterange: {
|
||||||
|
formatter: RANGE_FORMATTER,
|
||||||
|
parser: RANGE_PARSER
|
||||||
|
},
|
||||||
|
monthrange: {
|
||||||
|
formatter: RANGE_FORMATTER,
|
||||||
|
parser: RANGE_PARSER
|
||||||
|
},
|
||||||
|
datetimerange: {
|
||||||
|
formatter: RANGE_FORMATTER,
|
||||||
|
parser: RANGE_PARSER
|
||||||
|
},
|
||||||
|
timerange: {
|
||||||
|
formatter: RANGE_FORMATTER,
|
||||||
|
parser: RANGE_PARSER
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
formatter: DATE_FORMATTER,
|
||||||
|
parser: DATE_PARSER
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
formatter: DATE_FORMATTER,
|
||||||
|
parser: DATE_PARSER
|
||||||
|
},
|
||||||
|
year: {
|
||||||
|
formatter: DATE_FORMATTER,
|
||||||
|
parser: DATE_PARSER
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
formatter (value) {
|
||||||
|
if (!value) return ''
|
||||||
|
return '' + value
|
||||||
|
},
|
||||||
|
parser (text) {
|
||||||
|
const result = Number(text)
|
||||||
|
|
||||||
|
if (!isNaN(text)) {
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dates: {
|
||||||
|
formatter (value, format) {
|
||||||
|
return value.map(date => DATE_FORMATTER(date, format))
|
||||||
|
},
|
||||||
|
parser (value, format) {
|
||||||
|
return (typeof value === 'string' ? value.split(', ') : value)
|
||||||
|
.map(date => date instanceof Date ? date : DATE_PARSER(date, format))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const PLACEMENT_MAP = {
|
||||||
|
left: 'bottom-start',
|
||||||
|
center: 'bottom',
|
||||||
|
right: 'bottom-end'
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseAsFormatAndType = (value, customFormat, type, rangeSeparator = '-') => {
|
||||||
|
if (!value) return null
|
||||||
|
const parser = (
|
||||||
|
TYPE_VALUE_RESOLVER_MAP[type] ||
|
||||||
|
TYPE_VALUE_RESOLVER_MAP.default
|
||||||
|
).parser
|
||||||
|
const format = customFormat || DEFAULT_FORMATS[type]
|
||||||
|
return parser(value, format, rangeSeparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatAsFormatAndType = (value, customFormat, type) => {
|
||||||
|
if (!value) return null
|
||||||
|
const formatter = (
|
||||||
|
TYPE_VALUE_RESOLVER_MAP[type] ||
|
||||||
|
TYPE_VALUE_RESOLVER_MAP.default
|
||||||
|
).formatter
|
||||||
|
const format = customFormat || DEFAULT_FORMATS[type]
|
||||||
|
return formatter(value, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Considers:
|
||||||
|
* 1. Date object
|
||||||
|
* 2. date string
|
||||||
|
* 3. array of 1 or 2
|
||||||
|
*/
|
||||||
|
const valueEquals = function (a, b) {
|
||||||
|
// considers Date object and string
|
||||||
|
const dateEquals = function (a, b) {
|
||||||
|
const aIsDate = a instanceof Date
|
||||||
|
const bIsDate = b instanceof Date
|
||||||
|
if (aIsDate && bIsDate) {
|
||||||
|
return a.getTime() === b.getTime()
|
||||||
|
}
|
||||||
|
if (!aIsDate && !bIsDate) {
|
||||||
|
return a === b
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const aIsArray = a instanceof Array
|
||||||
|
const bIsArray = b instanceof Array
|
||||||
|
if (aIsArray && bIsArray) {
|
||||||
|
if (a.length !== b.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return a.every((item, index) => dateEquals(item, b[index]))
|
||||||
|
}
|
||||||
|
if (!aIsArray && !bIsArray) {
|
||||||
|
return dateEquals(a, b)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const isString = function (val) {
|
||||||
|
return typeof val === 'string' || val instanceof String
|
||||||
|
}
|
||||||
|
|
||||||
|
const validator = function (val) {
|
||||||
|
// either: String, Array of String, null / undefined
|
||||||
|
return (
|
||||||
|
val === null ||
|
||||||
|
val === undefined ||
|
||||||
|
isString(val) ||
|
||||||
|
(Array.isArray(val) && val.length === 2 && val.every(isString))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Emitter, NewPopper],
|
||||||
|
|
||||||
|
inject: {
|
||||||
|
elForm: {
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
elFormItem: {
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
size: String,
|
||||||
|
format: String,
|
||||||
|
valueFormat: String,
|
||||||
|
readonly: Boolean,
|
||||||
|
placeholder: String,
|
||||||
|
startPlaceholder: String,
|
||||||
|
endPlaceholder: String,
|
||||||
|
prefixIcon: String,
|
||||||
|
clearIcon: {
|
||||||
|
type: String,
|
||||||
|
default: 'el-icon-circle-close'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
default: '',
|
||||||
|
validator
|
||||||
|
},
|
||||||
|
disabled: Boolean,
|
||||||
|
clearable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
default: '',
|
||||||
|
validator
|
||||||
|
},
|
||||||
|
popperClass: String,
|
||||||
|
editable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
value: {},
|
||||||
|
defaultValue: {},
|
||||||
|
defaultTime: {},
|
||||||
|
rangeSeparator: {
|
||||||
|
default: '-'
|
||||||
|
},
|
||||||
|
pickerOptions: {},
|
||||||
|
unlinkPanels: Boolean,
|
||||||
|
validateEvent: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: { ElInput },
|
||||||
|
|
||||||
|
directives: { Clickoutside },
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
pickerVisible: false,
|
||||||
|
showClose: false,
|
||||||
|
userInput: null,
|
||||||
|
valueOnOpen: null, // value when picker opens, used to determine whether to emit change
|
||||||
|
unwatchPickerOptions: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
pickerVisible (val) {
|
||||||
|
if (this.readonly || this.pickerDisabled) return
|
||||||
|
if (val) {
|
||||||
|
this.showPicker()
|
||||||
|
this.valueOnOpen = Array.isArray(this.value) ? [...this.value] : this.value
|
||||||
|
} else {
|
||||||
|
this.hidePicker()
|
||||||
|
this.emitChange(this.value)
|
||||||
|
this.userInput = null
|
||||||
|
if (this.validateEvent) {
|
||||||
|
this.dispatch('ElFormItem', 'el.form.blur')
|
||||||
|
}
|
||||||
|
this.$emit('blur', this)
|
||||||
|
this.blur()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parsedValue: {
|
||||||
|
immediate: true,
|
||||||
|
handler (val) {
|
||||||
|
if (this.picker) {
|
||||||
|
this.picker.value = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultValue (val) {
|
||||||
|
// NOTE: should eventually move to jsx style picker + panel ?
|
||||||
|
if (this.picker) {
|
||||||
|
this.picker.defaultValue = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value (val, oldVal) {
|
||||||
|
if (!valueEquals(val, oldVal) && !this.pickerVisible && this.validateEvent) {
|
||||||
|
this.dispatch('ElFormItem', 'el.form.change', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
ranged () {
|
||||||
|
return this.type.indexOf('range') > -1
|
||||||
|
},
|
||||||
|
|
||||||
|
reference () {
|
||||||
|
const reference = this.$refs.reference
|
||||||
|
return reference.$el || reference
|
||||||
|
},
|
||||||
|
|
||||||
|
refInput () {
|
||||||
|
if (this.reference) {
|
||||||
|
return [].slice.call(this.reference.querySelectorAll('input'))
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
|
||||||
|
valueIsEmpty () {
|
||||||
|
const val = this.value
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
for (let i = 0, len = val.length; i < len; i++) {
|
||||||
|
if (val[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (val) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
|
triggerClass () {
|
||||||
|
return this.prefixIcon || (this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date')
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionMode () {
|
||||||
|
if (this.type === 'week') {
|
||||||
|
return 'week'
|
||||||
|
} else if (this.type === 'month') {
|
||||||
|
return 'month'
|
||||||
|
} else if (this.type === 'year') {
|
||||||
|
return 'year'
|
||||||
|
} else if (this.type === 'dates') {
|
||||||
|
return 'dates'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'day'
|
||||||
|
},
|
||||||
|
|
||||||
|
haveTrigger () {
|
||||||
|
if (typeof this.showTrigger !== 'undefined') {
|
||||||
|
return this.showTrigger
|
||||||
|
}
|
||||||
|
return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1
|
||||||
|
},
|
||||||
|
|
||||||
|
displayValue () {
|
||||||
|
const formattedValue = formatAsFormatAndType(this.parsedValue, this.format, this.type, this.rangeSeparator)
|
||||||
|
if (Array.isArray(this.userInput)) {
|
||||||
|
return [
|
||||||
|
this.userInput[0] || (formattedValue && formattedValue[0]) || '',
|
||||||
|
this.userInput[1] || (formattedValue && formattedValue[1]) || ''
|
||||||
|
]
|
||||||
|
} else if (this.userInput !== null) {
|
||||||
|
return this.userInput
|
||||||
|
} else if (formattedValue) {
|
||||||
|
return this.type === 'dates'
|
||||||
|
? formattedValue.join(', ')
|
||||||
|
: formattedValue
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parsedValue () {
|
||||||
|
if (!this.value) return this.value // component value is not set
|
||||||
|
if (this.type === 'time-select') return this.value // time-select does not require parsing, this might change in next major version
|
||||||
|
|
||||||
|
const valueIsDateObject = isDateObject(this.value) || (Array.isArray(this.value) && this.value.every(isDateObject))
|
||||||
|
if (valueIsDateObject) {
|
||||||
|
return this.value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.valueFormat) {
|
||||||
|
return parseAsFormatAndType(this.value, this.valueFormat, this.type, this.rangeSeparator) || this.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: deal with common but incorrect usage, should remove in next major version
|
||||||
|
// user might provide string / timestamp without value-format, coerce them into date (or array of date)
|
||||||
|
return Array.isArray(this.value) ? this.value.map(val => new Date(val)) : new Date(this.value)
|
||||||
|
},
|
||||||
|
|
||||||
|
_elFormItemSize () {
|
||||||
|
return (this.elFormItem || {}).elFormItemSize
|
||||||
|
},
|
||||||
|
|
||||||
|
pickerSize () {
|
||||||
|
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size
|
||||||
|
},
|
||||||
|
|
||||||
|
pickerDisabled () {
|
||||||
|
return this.disabled || (this.elForm || {}).disabled
|
||||||
|
},
|
||||||
|
|
||||||
|
firstInputId () {
|
||||||
|
const obj = {}
|
||||||
|
let id
|
||||||
|
if (this.ranged) {
|
||||||
|
id = this.id && this.id[0]
|
||||||
|
} else {
|
||||||
|
id = this.id
|
||||||
|
}
|
||||||
|
if (id) obj.id = id
|
||||||
|
return obj
|
||||||
|
},
|
||||||
|
|
||||||
|
secondInputId () {
|
||||||
|
const obj = {}
|
||||||
|
let id
|
||||||
|
if (this.ranged) {
|
||||||
|
id = this.id && this.id[1]
|
||||||
|
}
|
||||||
|
if (id) obj.id = id
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
// vue-popper
|
||||||
|
this.popperOptions = {
|
||||||
|
boundariesPadding: 0,
|
||||||
|
gpuAcceleration: false
|
||||||
|
}
|
||||||
|
this.placement = PLACEMENT_MAP[this.align] || PLACEMENT_MAP.left
|
||||||
|
|
||||||
|
this.$on('fieldReset', this.handleFieldReset)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
focus () {
|
||||||
|
if (!this.ranged) {
|
||||||
|
this.$refs.reference.focus()
|
||||||
|
} else {
|
||||||
|
this.handleFocus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
blur () {
|
||||||
|
this.refInput.forEach(input => input.blur())
|
||||||
|
},
|
||||||
|
|
||||||
|
// {parse, formatTo} Value deals maps component value with internal Date
|
||||||
|
parseValue (value) {
|
||||||
|
const isParsed = isDateObject(value) || (Array.isArray(value) && value.every(isDateObject))
|
||||||
|
if (this.valueFormat && !isParsed) {
|
||||||
|
return parseAsFormatAndType(value, this.valueFormat, this.type, this.rangeSeparator) || value
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
formatToValue (date) {
|
||||||
|
const isFormattable = isDateObject(date) || (Array.isArray(date) && date.every(isDateObject))
|
||||||
|
if (this.valueFormat && isFormattable) {
|
||||||
|
return formatAsFormatAndType(date, this.valueFormat, this.type, this.rangeSeparator)
|
||||||
|
} else {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// {parse, formatTo} String deals with user input
|
||||||
|
parseString (value) {
|
||||||
|
const type = Array.isArray(value) ? this.type : this.type.replace('range', '')
|
||||||
|
return parseAsFormatAndType(value, this.format, type)
|
||||||
|
},
|
||||||
|
|
||||||
|
formatToString (value) {
|
||||||
|
const type = Array.isArray(value) ? this.type : this.type.replace('range', '')
|
||||||
|
return formatAsFormatAndType(value, this.format, type)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMouseEnter () {
|
||||||
|
if (this.readonly || this.pickerDisabled) return
|
||||||
|
if (!this.valueIsEmpty && this.clearable) {
|
||||||
|
this.showClose = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleChange () {
|
||||||
|
if (this.userInput) {
|
||||||
|
const value = this.parseString(this.displayValue)
|
||||||
|
if (value) {
|
||||||
|
this.picker.value = value
|
||||||
|
if (this.isValidValue(value)) {
|
||||||
|
this.emitInput(value)
|
||||||
|
this.userInput = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.userInput === '') {
|
||||||
|
this.emitInput(null)
|
||||||
|
this.emitChange(null)
|
||||||
|
this.userInput = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleStartInput (event) {
|
||||||
|
if (this.userInput) {
|
||||||
|
this.userInput = [event.target.value, this.userInput[1]]
|
||||||
|
} else {
|
||||||
|
this.userInput = [event.target.value, null]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEndInput (event) {
|
||||||
|
if (this.userInput) {
|
||||||
|
this.userInput = [this.userInput[0], event.target.value]
|
||||||
|
} else {
|
||||||
|
this.userInput = [null, event.target.value]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleStartChange (event) {
|
||||||
|
const value = this.parseString(this.userInput && this.userInput[0])
|
||||||
|
if (value) {
|
||||||
|
this.userInput = [this.formatToString(value), this.displayValue[1]]
|
||||||
|
const newValue = [value, this.picker.value && this.picker.value[1]]
|
||||||
|
this.picker.value = newValue
|
||||||
|
if (this.isValidValue(newValue)) {
|
||||||
|
this.emitInput(newValue)
|
||||||
|
this.userInput = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEndChange (event) {
|
||||||
|
const value = this.parseString(this.userInput && this.userInput[1])
|
||||||
|
if (value) {
|
||||||
|
this.userInput = [this.displayValue[0], this.formatToString(value)]
|
||||||
|
const newValue = [this.picker.value && this.picker.value[0], value]
|
||||||
|
this.picker.value = newValue
|
||||||
|
if (this.isValidValue(newValue)) {
|
||||||
|
this.emitInput(newValue)
|
||||||
|
this.userInput = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClickIcon (event) {
|
||||||
|
if (this.readonly || this.pickerDisabled) return
|
||||||
|
if (this.showClose) {
|
||||||
|
this.valueOnOpen = this.value
|
||||||
|
event.stopPropagation()
|
||||||
|
this.emitInput(null)
|
||||||
|
this.emitChange(null)
|
||||||
|
this.showClose = false
|
||||||
|
if (this.picker && typeof this.picker.handleClear === 'function') {
|
||||||
|
this.picker.handleClear()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.pickerVisible = !this.pickerVisible
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleClose () {
|
||||||
|
if (!this.pickerVisible) return
|
||||||
|
this.pickerVisible = false
|
||||||
|
|
||||||
|
if (this.type === 'dates') {
|
||||||
|
// restore to former value
|
||||||
|
const oldValue = parseAsFormatAndType(this.valueOnOpen, this.valueFormat, this.type, this.rangeSeparator) || this.valueOnOpen
|
||||||
|
this.emitInput(oldValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFieldReset (initialValue) {
|
||||||
|
this.userInput = initialValue === '' ? null : initialValue
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFocus () {
|
||||||
|
const type = this.type
|
||||||
|
|
||||||
|
if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
|
||||||
|
this.pickerVisible = true
|
||||||
|
}
|
||||||
|
this.$emit('focus', this)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeydown (event) {
|
||||||
|
const keyCode = event.keyCode
|
||||||
|
|
||||||
|
// ESC
|
||||||
|
if (keyCode === 27) {
|
||||||
|
this.pickerVisible = false
|
||||||
|
event.stopPropagation()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab
|
||||||
|
if (keyCode === 9) {
|
||||||
|
if (!this.ranged) {
|
||||||
|
this.handleChange()
|
||||||
|
this.pickerVisible = this.picker.visible = false
|
||||||
|
this.blur()
|
||||||
|
event.stopPropagation()
|
||||||
|
} else {
|
||||||
|
// user may change focus between two input
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.refInput.indexOf(document.activeElement) === -1) {
|
||||||
|
this.pickerVisible = false
|
||||||
|
this.blur()
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enter
|
||||||
|
if (keyCode === 13) {
|
||||||
|
if (this.userInput === '' || this.isValidValue(this.parseString(this.displayValue))) {
|
||||||
|
this.handleChange()
|
||||||
|
this.pickerVisible = this.picker.visible = false
|
||||||
|
this.blur()
|
||||||
|
}
|
||||||
|
event.stopPropagation()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if user is typing, do not let picker handle key input
|
||||||
|
if (this.userInput) {
|
||||||
|
event.stopPropagation()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// delegate other keys to panel
|
||||||
|
if (this.picker && this.picker.handleKeydown) {
|
||||||
|
this.picker.handleKeydown(event)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleRangeClick () {
|
||||||
|
const type = this.type
|
||||||
|
|
||||||
|
if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
|
||||||
|
this.pickerVisible = true
|
||||||
|
}
|
||||||
|
this.$emit('focus', this)
|
||||||
|
},
|
||||||
|
|
||||||
|
hidePicker () {
|
||||||
|
if (this.picker) {
|
||||||
|
this.picker.resetView && this.picker.resetView()
|
||||||
|
this.pickerVisible = this.picker.visible = false
|
||||||
|
this.destroyPopper()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showPicker () {
|
||||||
|
if (this.$isServer) return
|
||||||
|
if (!this.picker) {
|
||||||
|
this.mountPicker()
|
||||||
|
}
|
||||||
|
this.pickerVisible = this.picker.visible = true
|
||||||
|
|
||||||
|
this.updatePopper()
|
||||||
|
|
||||||
|
this.picker.value = this.parsedValue
|
||||||
|
this.picker.resetView && this.picker.resetView()
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.picker.adjustSpinners && this.picker.adjustSpinners()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
mountPicker () {
|
||||||
|
this.picker = new Vue(this.panel).$mount()
|
||||||
|
this.picker.defaultValue = this.defaultValue
|
||||||
|
this.picker.defaultTime = this.defaultTime
|
||||||
|
this.picker.popperClass = this.popperClass
|
||||||
|
this.popperElm = this.picker.$el
|
||||||
|
this.picker.width = this.reference.getBoundingClientRect().width
|
||||||
|
this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange'
|
||||||
|
this.picker.selectionMode = this.selectionMode
|
||||||
|
this.picker.unlinkPanels = this.unlinkPanels
|
||||||
|
this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false
|
||||||
|
this.$watch('format', (format) => {
|
||||||
|
this.picker.format = format
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateOptions = () => {
|
||||||
|
const options = this.pickerOptions
|
||||||
|
|
||||||
|
if (options && options.selectableRange) {
|
||||||
|
let ranges = options.selectableRange
|
||||||
|
const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser
|
||||||
|
const format = DEFAULT_FORMATS.timerange
|
||||||
|
|
||||||
|
ranges = Array.isArray(ranges) ? ranges : [ranges]
|
||||||
|
this.picker.selectableRange = ranges.map(range => parser(range, format, this.rangeSeparator))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const option in options) {
|
||||||
|
if (options.hasOwnProperty(option) &&
|
||||||
|
// 忽略 time-picker 的该配置项
|
||||||
|
option !== 'selectableRange') {
|
||||||
|
this.picker[option] = options[option]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// main format must prevail over undocumented pickerOptions.format
|
||||||
|
if (this.format) {
|
||||||
|
this.picker.format = this.format
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateOptions()
|
||||||
|
this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true })
|
||||||
|
this.$el.appendChild(this.picker.$el)
|
||||||
|
this.picker.resetView && this.picker.resetView()
|
||||||
|
|
||||||
|
this.picker.$on('dodestroy', this.doDestroy)
|
||||||
|
this.picker.$on('pick', (date = '', visible = false) => {
|
||||||
|
this.userInput = null
|
||||||
|
this.pickerVisible = this.picker.visible = visible
|
||||||
|
this.emitInput(date)
|
||||||
|
this.picker.resetView && this.picker.resetView()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.picker.$on('select-range', (start, end, pos) => {
|
||||||
|
if (this.refInput.length === 0) return
|
||||||
|
if (!pos || pos === 'min') {
|
||||||
|
this.refInput[0].setSelectionRange(start, end)
|
||||||
|
this.refInput[0].focus()
|
||||||
|
} else if (pos === 'max') {
|
||||||
|
this.refInput[1].setSelectionRange(start, end)
|
||||||
|
this.refInput[1].focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
unmountPicker () {
|
||||||
|
if (this.picker) {
|
||||||
|
this.picker.$destroy()
|
||||||
|
this.picker.$off()
|
||||||
|
if (typeof this.unwatchPickerOptions === 'function') {
|
||||||
|
this.unwatchPickerOptions()
|
||||||
|
}
|
||||||
|
this.picker.$el.parentNode.removeChild(this.picker.$el)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emitChange (val) {
|
||||||
|
// determine user real change only
|
||||||
|
if (!valueEquals(val, this.valueOnOpen)) {
|
||||||
|
this.$emit('change', val)
|
||||||
|
this.valueOnOpen = val
|
||||||
|
if (this.validateEvent) {
|
||||||
|
this.dispatch('ElFormItem', 'el.form.change', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emitInput (val) {
|
||||||
|
const formatted = this.formatToValue(val)
|
||||||
|
if (!valueEquals(this.value, formatted)) {
|
||||||
|
this.$emit('input', formatted)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isValidValue (value) {
|
||||||
|
if (!this.picker) {
|
||||||
|
this.mountPicker()
|
||||||
|
}
|
||||||
|
if (this.picker.isValidValue) {
|
||||||
|
return value && this.picker.isValidValue(value)
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import Picker from '../picker'
|
||||||
|
import DatePanel from '../panel/date'
|
||||||
|
import DateRangePanel from '../panel/date-range'
|
||||||
|
import MonthRangePanel from '../panel/month-range'
|
||||||
|
|
||||||
|
const getPanel = function (type) {
|
||||||
|
if (type === 'daterange' || type === 'datetimerange') {
|
||||||
|
return DateRangePanel
|
||||||
|
} else if (type === 'monthrange') {
|
||||||
|
return MonthRangePanel
|
||||||
|
}
|
||||||
|
return DatePanel
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Picker],
|
||||||
|
|
||||||
|
name: 'ElDatePicker',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'date'
|
||||||
|
},
|
||||||
|
timeArrowControl: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
type (type) {
|
||||||
|
if (this.picker) {
|
||||||
|
this.unmountPicker()
|
||||||
|
this.panel = getPanel(type)
|
||||||
|
this.mountPicker()
|
||||||
|
} else {
|
||||||
|
this.panel = getPanel(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.panel = getPanel(this.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import Picker from '../picker'
|
||||||
|
import TimePanel from '../panel/time'
|
||||||
|
import TimeRangePanel from '../panel/time-range'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Picker],
|
||||||
|
|
||||||
|
name: 'ElTimePicker',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
isRange: Boolean,
|
||||||
|
arrowControl: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
type: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
isRange (isRange) {
|
||||||
|
if (this.picker) {
|
||||||
|
this.unmountPicker()
|
||||||
|
this.type = isRange ? 'timerange' : 'time'
|
||||||
|
this.panel = isRange ? TimeRangePanel : TimePanel
|
||||||
|
this.mountPicker()
|
||||||
|
} else {
|
||||||
|
this.type = isRange ? 'timerange' : 'time'
|
||||||
|
this.panel = isRange ? TimeRangePanel : TimePanel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.type = this.isRange ? 'timerange' : 'time'
|
||||||
|
this.panel = this.isRange ? TimeRangePanel : TimePanel
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import Picker from '../picker'
|
||||||
|
import Panel from '../panel/time-select'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [Picker],
|
||||||
|
|
||||||
|
name: 'ElTimeSelect',
|
||||||
|
|
||||||
|
componentName: 'ElTimeSelect',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'time-select'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeCreate () {
|
||||||
|
this.panel = Panel
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -129,7 +129,7 @@ export default {
|
|||||||
type: Object
|
type: Object
|
||||||
},
|
},
|
||||||
tableTitle: {
|
tableTitle: {
|
||||||
type: Array,
|
type: Array
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
|||||||
@@ -0,0 +1,344 @@
|
|||||||
|
<template>
|
||||||
|
<el-dropdown :size="size">
|
||||||
|
<button id="more" :class="triggerButtonClass" title="more...">
|
||||||
|
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px;"></i>
|
||||||
|
</button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<!-- <el-dropdown-item>
|
||||||
|
<div @click="panelLock=!panelLock" id="panel-lock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i>{{panelLock ? 'Locked' : 'Unlocked'}}</div>
|
||||||
|
</el-dropdown-item>-->
|
||||||
|
<slot name="before"></slot>
|
||||||
|
<el-dropdown-item v-if="importUrl">
|
||||||
|
<div id="chart-import" @click="showImportBox(1)"><i class="nz-icon nz-icon-upload"></i>{{$t('overall.importExcel')}}</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-if="exportUrl">
|
||||||
|
<div id="chart-export"@click="showImportBox(2)"><i class="nz-icon nz-icon-download1"></i>{{$t('overall.exportExcel')}}</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<slot name="after"></slot>
|
||||||
|
<!-- <el-dropdown-item v-has="'panel_chart_add'">
|
||||||
|
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-download1"></i>Add template</div>
|
||||||
|
</el-dropdown-item>-->
|
||||||
|
</el-dropdown-menu>
|
||||||
|
|
||||||
|
<el-dialog :close-on-click-modal="importBox.type!=3" :show-close="true" :title="importBox.title" :visible.sync="importBox.show" :width="importBox.width" append-to-body class="nz-dialog" @close="closeDialog">
|
||||||
|
<div v-if="importBox.type == 1">
|
||||||
|
<div class="upload-body">
|
||||||
|
<el-upload :id="id+'-xlsx-input-file'" ref="uploadExcel" :auto-upload="false" :file-list="importFileList" :on-change="importChange" accept=".xlsx,.xls" action="" class="upload-demo" drag>
|
||||||
|
<div slot="tip" class="el-upload__tip" >{{$t('overall.importTip')}}</div>
|
||||||
|
<i class="nz-icon nz-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">{{$t('overall.dragFileTip')}},{{$t('overall.or')}} <em>{{$t('overall.clickUpload')}}</em></div>
|
||||||
|
<!--<button type="button" class="nz-btn nz-btn-size-normal nz-btn-style-normal">
|
||||||
|
<span class="top-tool-btn-txt" >{{$t('overall.upload')}}</span>
|
||||||
|
</button>-->
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="footer">
|
||||||
|
<div class="el-message-box__btns" style="text-align: right;">
|
||||||
|
<button :id="id+'-xlsx-import-template'" class="el-button el-button--default el-button--small" @click="downloadTemplate">
|
||||||
|
<span>{{$t('overall.template')}}</span>
|
||||||
|
</button>
|
||||||
|
<button :id="id+'-xlsx-import-add'" :class="{'nz-btn-disabled':prevent_opt.import}" :disabled="prevent_opt.import" class="nz-btn el-button el-button--default el-button--small" @click="importExcel">
|
||||||
|
<span>{{$t('overall.importExcel')}}</span>
|
||||||
|
</button>
|
||||||
|
<button :id="id+'-xlsx-import-esc'" class="el-button el-button--default el-button--small" @click="closeDialog">
|
||||||
|
<span>{{$t('overall.cancel')}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="importBox.type == 2">
|
||||||
|
<div class="upload-body">
|
||||||
|
<button :id="id+'-xlsx-export-current'" class="el-button el-button--default el-button--small" @click="exportCur">
|
||||||
|
<span>{{$t('overall.exportCur')}}</span>
|
||||||
|
</button>
|
||||||
|
<button :id="id+'-xlsx-export-all'" class="el-button el-button--default el-button--small" @click="exportAll">
|
||||||
|
<span>{{$t('overall.exportAll')}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="footer">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="importBox.type==3">
|
||||||
|
<div class="upload-body result-body">
|
||||||
|
<div>
|
||||||
|
<span class="result-title">{{$t('overall.result.total')}}:</span>
|
||||||
|
<span>{{importResult&&importResult.totalNum?importResult.totalNum:0}}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="result-title">{{$t('overall.result.failed')}}:</span>
|
||||||
|
<span>{{importResult&&importResult.failNum?importResult.failNum:0}}</span>
|
||||||
|
<span class="result-title">{{$t('overall.result.success')}}:</span>
|
||||||
|
<span>{{importResult&&importResult.successNum?importResult.successNum:0}}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="result-title">{{$t('overall.result.failedDetail')}}:</div>
|
||||||
|
<div v-if="importResult&&importResult.failDetail" class="result-detail">
|
||||||
|
<div style="height: 100%; overflow: auto;">
|
||||||
|
<!-- <ul>
|
||||||
|
<li v-for="(item,index) in importResult.failDetail"><span>{{item.lineNo}}</span>:<span>{{item.errorMsg}}</span> </li>
|
||||||
|
</ul>-->
|
||||||
|
<template v-for="(item, index) in importResult.failDetail">
|
||||||
|
<div :key="index" class="import-result-block">
|
||||||
|
<div class="import-result-item">
|
||||||
|
<div class="line-num">{{$t('overall.result.line',[item.lineNo])}}</div>
|
||||||
|
<div>{{item.errorMsg}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="footer">
|
||||||
|
<div class="el-message-box__btns">
|
||||||
|
<button :id="id+'-xlsx-import-rollback'" class="nz-btn nz-btn-size-normal-new nz-btn-style-error-new" @click="rollbackImport">
|
||||||
|
<span>{{$t('overall.rollbackImport')}}</span>
|
||||||
|
</button>
|
||||||
|
<!--<button @click="closeDialog" class="el-button el-button--default el-button--small">-->
|
||||||
|
<!--<span>{{$t('overall.cancel')}}</span>-->
|
||||||
|
<!--</button>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
|
let timeout
|
||||||
|
export default {
|
||||||
|
name: 'topToolMoreOptions',
|
||||||
|
props: {
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: 'small'
|
||||||
|
},
|
||||||
|
exportUrl: { type: String, default: '' },
|
||||||
|
params: { type: Object },
|
||||||
|
exportFileName: { type: String },
|
||||||
|
importUrl: { type: String, default: '' }, // 为空时不显示导入按钮
|
||||||
|
link: { type: Object }, // 为空时不显示导出按钮
|
||||||
|
permissions: { type: Object },
|
||||||
|
showCur: { type: Boolean, default: true },
|
||||||
|
id: { type: String, default: 'export' },
|
||||||
|
triggerButtonClass: { // 触发下拉事件的按钮的class
|
||||||
|
type: String,
|
||||||
|
default: 'top-tool-btn'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
importBox: { show: false, title: this.$t('overall.importExcel'), type: 1 },
|
||||||
|
importFile: null,
|
||||||
|
importFileList: [],
|
||||||
|
importResult: null,
|
||||||
|
exportShow: false,
|
||||||
|
paramsType: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.getParamsType()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
importChange (file, fileList) {
|
||||||
|
if (fileList.length > 0) {
|
||||||
|
this.importFileList = [fileList[fileList.length - 1]]
|
||||||
|
}
|
||||||
|
this.importFile = this.importFileList[0]
|
||||||
|
this.validateFile()
|
||||||
|
},
|
||||||
|
validateFile () {
|
||||||
|
|
||||||
|
},
|
||||||
|
rollbackImport () {
|
||||||
|
let url
|
||||||
|
if (this.importUrl.indexOf('asset') > -1) {
|
||||||
|
url = '/asset/cancelImport'
|
||||||
|
} else if (this.importUrl.indexOf('endpoint') > -1) {
|
||||||
|
url = '/monitor/endpoint/cancelImport'
|
||||||
|
} else if (this.importUrl.indexOf('rule') > -1) {
|
||||||
|
url = '/alert/rule/cancelImport'
|
||||||
|
} else if (this.importUrl.indexOf('panel') > -1) {
|
||||||
|
url = '/panel/cancelImport'
|
||||||
|
} else if (this.importUrl.indexOf('tmpl') > -1) {
|
||||||
|
url = '/expression/tmpl/cancelImport'
|
||||||
|
}
|
||||||
|
this.$delete(url + '?seq=' + this.importResult.seq).then(response => {
|
||||||
|
if (response.code == 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
this.$emit('afterImport')
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.msg)
|
||||||
|
}
|
||||||
|
this.closeDialog()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
importExcel () {
|
||||||
|
if (this.importFile && this.importFile.raw) {
|
||||||
|
this.prevent_opt.import = true
|
||||||
|
const form = new FormData()
|
||||||
|
form.append('excelFile', this.importFile.raw)
|
||||||
|
if (this.paramsType) {
|
||||||
|
form.append('type', this.paramsType)
|
||||||
|
if (this.paramsType === 'asset' || this.paramsType === 'model') {
|
||||||
|
form.append('linkId', this.link ? this.link.id : '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form.append('language', localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en')
|
||||||
|
this.$post(this.importUrl, form, { 'Content-Type': 'multipart/form-data' }).then(response => {
|
||||||
|
if (response.code == 200 && response.msg == 'success') {
|
||||||
|
this.importResult = response.data
|
||||||
|
this.$emit('afterImport')
|
||||||
|
this.importBox.type = 3
|
||||||
|
this.importBox.width = '600px'
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.msg)
|
||||||
|
}
|
||||||
|
this.prevent_opt.import = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error(this.$t('tip.noImportFile'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
exportMenuHandler (show) {
|
||||||
|
if (show) {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
this.exportShow = true
|
||||||
|
} else {
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
this.exportShow = false
|
||||||
|
}, 700)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeDialog () {
|
||||||
|
this.importBox.show = false
|
||||||
|
this.importResult = null
|
||||||
|
this.importFileList = []
|
||||||
|
this.importFile = null
|
||||||
|
},
|
||||||
|
downloadTemplate () {
|
||||||
|
const language = localStorage.getItem('nz-language') || 'en' // 初始未选择默认 en 英文
|
||||||
|
const fileName = this.exportFileName + '-' + this.$t('overall.template') + '-' + this.getTimeString() + '.xlsx'
|
||||||
|
|
||||||
|
let url = null
|
||||||
|
if (this.importUrl.indexOf('asset') > -1) {
|
||||||
|
url = '/asset/template'
|
||||||
|
} else if (this.importUrl.indexOf('rule') > -1) {
|
||||||
|
url = '/alert/rule/template'
|
||||||
|
} else if (this.importUrl.indexOf('panel') > -1) {
|
||||||
|
url = '/panel/template'
|
||||||
|
} else if (this.importUrl.indexOf('endpoint') > -1) {
|
||||||
|
url = '/monitor/endpoint/template'
|
||||||
|
} else if (this.importUrl.indexOf('tmpl') > -1) {
|
||||||
|
url = '/expression/tmpl/template'
|
||||||
|
}
|
||||||
|
|
||||||
|
const param = { language: language }
|
||||||
|
if (!url) {
|
||||||
|
console.error('no interface support')
|
||||||
|
}
|
||||||
|
this.exportExcel(url, param, fileName)
|
||||||
|
},
|
||||||
|
formatJson (filterVal, jsonData) {
|
||||||
|
return jsonData.map(v => filterVal.map(j => v[j]))
|
||||||
|
},
|
||||||
|
exportCur () {
|
||||||
|
const params = Object.assign({}, this.params)
|
||||||
|
params.language = localStorage.getItem('nz-language') || 'en'
|
||||||
|
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
|
||||||
|
this.closeDialog()
|
||||||
|
},
|
||||||
|
exportAll () {
|
||||||
|
const params = JSON.parse(JSON.stringify(this.params))
|
||||||
|
params.pageSize = -1
|
||||||
|
if (this.importUrl.indexOf('panel') > -1) {
|
||||||
|
delete params.panelId
|
||||||
|
}
|
||||||
|
// if (this.importUrl.indexOf('endpoint') > -1){
|
||||||
|
// delete params.moduleId
|
||||||
|
// }
|
||||||
|
params.language = localStorage.getItem('nz-language') || 'en'
|
||||||
|
|
||||||
|
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
|
||||||
|
this.closeDialog()
|
||||||
|
},
|
||||||
|
exportExcel (url, params, fileName) {
|
||||||
|
if (this.paramsType) {
|
||||||
|
params.type = this.paramsType
|
||||||
|
}
|
||||||
|
axios.get(url, { responseType: 'blob', params: params }).then(res => {
|
||||||
|
if (window.navigator.msSaveOrOpenBlob) {
|
||||||
|
// 兼容ie11
|
||||||
|
const blobObject = new Blob([res.data])
|
||||||
|
window.navigator.msSaveOrOpenBlob(blobObject, fileName)
|
||||||
|
} else {
|
||||||
|
const url = URL.createObjectURL(new Blob([res.data]))
|
||||||
|
const a = document.createElement('a')
|
||||||
|
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.target = '_blank'
|
||||||
|
a.click()
|
||||||
|
a.remove() // 将a标签移除
|
||||||
|
}
|
||||||
|
}, error => {
|
||||||
|
const $self = this
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = function (event) {
|
||||||
|
const responseText = reader.result
|
||||||
|
const exception = JSON.parse(responseText)
|
||||||
|
if (exception.message) {
|
||||||
|
$self.$message.error(exception.message)
|
||||||
|
} else {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsText(error.response.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
showImportBox (type) {
|
||||||
|
this.importBox.show = true
|
||||||
|
this.importBox.type = type
|
||||||
|
if (type == 2 && (!this.showCur)) {
|
||||||
|
this.exportCur()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (type == 1) { // import
|
||||||
|
this.importBox.title = this.$t('overall.importExcel')
|
||||||
|
this.importBox.width = '600px'
|
||||||
|
} else if (type == 2) { // export
|
||||||
|
this.importBox.title = this.$t('overall.exportExcel')
|
||||||
|
this.importBox.width = '300px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTimeString () {
|
||||||
|
const split = '-'
|
||||||
|
const date = new Date()
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = this.formatNum(date.getMonth() + 1)
|
||||||
|
const day = this.formatNum(date.getDate())
|
||||||
|
const hours = this.formatNum(date.getHours())
|
||||||
|
const minutes = this.formatNum(date.getMinutes())
|
||||||
|
const seconds = this.formatNum(date.getSeconds())
|
||||||
|
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
|
||||||
|
},
|
||||||
|
formatNum (num) {
|
||||||
|
return num > 9 ? num : '0' + num
|
||||||
|
},
|
||||||
|
getParamsType () {
|
||||||
|
const path = this.$route.path
|
||||||
|
switch (path) {
|
||||||
|
case '/panel': this.paramsType = 'dashboard'; break
|
||||||
|
case '/asset': this.paramsType = 'asset'; break
|
||||||
|
case '/model': this.paramsType = 'model'; break
|
||||||
|
default: this.paramsType = ''; break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1562,7 +1562,7 @@ export default {
|
|||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
this.uploadPicShow = false
|
this.uploadPicShow = false
|
||||||
this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => {
|
this.dealImg(`monitor/project/topo/icon/${res.data.id}/1`).then((data) => {
|
||||||
const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
|
const group = this.tools.find(tool => tool.group === this.uploadPic.unit)
|
||||||
if (group) {
|
if (group) {
|
||||||
group.children.push({
|
group.children.push({
|
||||||
@@ -1618,7 +1618,7 @@ export default {
|
|||||||
res.data.list.forEach((item, index) => {
|
res.data.list.forEach((item, index) => {
|
||||||
item.imageName = item.name
|
item.imageName = item.name
|
||||||
delete item.name
|
delete item.name
|
||||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`))
|
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}/1`))
|
||||||
imgArr.push({ ...item })
|
imgArr.push({ ...item })
|
||||||
})
|
})
|
||||||
Promise.all(promiseArr).then((res2) => {
|
Promise.all(promiseArr).then((res2) => {
|
||||||
@@ -1662,7 +1662,7 @@ export default {
|
|||||||
const promiseArr = []
|
const promiseArr = []
|
||||||
imgidList.forEach((item, index) => {
|
imgidList.forEach((item, index) => {
|
||||||
if (item.data.imageId) {
|
if (item.data.imageId) {
|
||||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`))
|
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}/1`))
|
||||||
} else {
|
} else {
|
||||||
promiseArr.push('')
|
promiseArr.push('')
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -65,6 +65,7 @@
|
|||||||
:sort-orders="['ascending', 'descending']"
|
:sort-orders="['ascending', 'descending']"
|
||||||
:width="`${item.width}`"
|
:width="`${item.width}`"
|
||||||
class="data-column"
|
class="data-column"
|
||||||
|
|
||||||
>
|
>
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
<span>{{item.label}}</span>
|
<span>{{item.label}}</span>
|
||||||
@@ -75,19 +76,19 @@
|
|||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop].name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop == 'model'">
|
<template v-else-if="item.prop == 'model'">
|
||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop]?scope.row[item.prop].name : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop == 'dc'">
|
<template v-else-if="item.prop == 'dc'">
|
||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop]?scope.row[item.prop].name : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop == 'cabinet'">
|
<template v-else-if="item.prop == 'cabinet'">
|
||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop]?scope.row[item.prop].name : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop == 'type'">
|
<template v-else-if="item.prop == 'type'">
|
||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop]?scope.row[item.prop].name : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop == 'state'">
|
<template v-else-if="item.prop == 'state'">
|
||||||
<span>{{scope.row[item.prop].name}}</span>
|
<span>{{scope.row[item.prop]?scope.row[item.prop].name : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{scope.row[item.prop] ? scope.row[item.prop] : ''}}</span>
|
<span v-else>{{scope.row[item.prop] ? scope.row[item.prop] : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -264,7 +265,7 @@ export default {
|
|||||||
labelModule: [],
|
labelModule: [],
|
||||||
basic_auth: {
|
basic_auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
pin: ''
|
||||||
},
|
},
|
||||||
bearer_token: ''
|
bearer_token: ''
|
||||||
},
|
},
|
||||||
@@ -754,13 +755,13 @@ export default {
|
|||||||
currentModuleCopy: {
|
currentModuleCopy: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
handler (n, o) {
|
handler (n, o) {
|
||||||
if (n.type && n.type.toLowerCase() == 'snmp') {
|
// if (n.type && n.type.toLowerCase() == 'snmp') {
|
||||||
this.endpointTableTitle[4].show = false
|
// this.endpointTableTitle[4].show = false
|
||||||
this.endpointTableTitle[5].show = false
|
// this.endpointTableTitle[5].show = false
|
||||||
} else {
|
// } else {
|
||||||
this.endpointTableTitle[4].show = true
|
// this.endpointTableTitle[4].show = true
|
||||||
this.endpointTableTitle[5].show = true
|
// this.endpointTableTitle[5].show = true
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1130,7 +1131,7 @@ export default {
|
|||||||
.add-endpoint{
|
.add-endpoint{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: #F9F9F9;
|
background: #F9F9F9;
|
||||||
border: 1px solid $--primary-border-color;
|
border: 1px solid #dedede;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
@@ -1141,7 +1142,7 @@ export default {
|
|||||||
.top-tool-btn{
|
.top-tool-btn{
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
border: 1px solid $--primary-border-color;
|
border: 1px solid #dedede;
|
||||||
outline: none;
|
outline: none;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: #F9F9F9;
|
background-color: #F9F9F9;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import selectWalk from '../../popBox/selectWalk'
|
|||||||
export default {
|
export default {
|
||||||
name: 'modelBox',
|
name: 'modelBox',
|
||||||
components: {
|
components: {
|
||||||
'select-walk': selectWalk,
|
'select-walk': selectWalk
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
obj: {
|
obj: {
|
||||||
@@ -80,22 +80,22 @@ export default {
|
|||||||
editModule: {},
|
editModule: {},
|
||||||
chartlList: [], // chart 列表数据
|
chartlList: [], // chart 列表数据
|
||||||
ChartSearchShowFields: [ // ChartSearch 下拉搜索表头
|
ChartSearchShowFields: [ // ChartSearch 下拉搜索表头
|
||||||
{title: 'id',data: 'id'},
|
{ title: 'id', data: 'id' },
|
||||||
{title: 'name',data: 'name'},
|
{ title: 'name', data: 'name' },
|
||||||
{title: 'desc',data: 'type'},
|
{ title: 'desc', data: 'type' },
|
||||||
{title: 'Description',data: 'Description'}
|
{ title: 'Description', data: 'Description' }
|
||||||
],
|
],
|
||||||
url: 'asset/model',
|
url: 'asset/model',
|
||||||
brandUrl: 'asset/brand',
|
brandUrl: 'asset/brand',
|
||||||
rightBox: { model: { show: false } },
|
rightBox: { model: { show: false } },
|
||||||
roles: [],
|
roles: [],
|
||||||
rules: {
|
rules: {
|
||||||
model: [
|
model: [
|
||||||
{ required: true, message: '必填', trigger: 'blur' }
|
{ required: true, message: '必填', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
brandId: [
|
brandId: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -125,7 +125,7 @@ export default {
|
|||||||
this.$refs.modelForm.validate((valid) => {
|
this.$refs.modelForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.editModel.id) {
|
if (this.editModel.id) {
|
||||||
console.log(this.editModel);
|
console.log(this.editModel)
|
||||||
this.$put(this.url, this.editModel).then(res => {
|
this.$put(this.url, this.editModel).then(res => {
|
||||||
this.prevent_opt.save = false
|
this.prevent_opt.save = false
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
@@ -154,7 +154,7 @@ export default {
|
|||||||
},
|
},
|
||||||
save () {
|
save () {
|
||||||
if (typeof this.editModel.brandId === 'string') { // 判断是否是新增的
|
if (typeof this.editModel.brandId === 'string') { // 判断是否是新增的
|
||||||
this.$post(this.brandUrl, {name: this.editModel.brandId}).then(res => {
|
this.$post(this.brandUrl, { name: this.editModel.brandId }).then(res => {
|
||||||
if (res.code === 200) { // 新增成功
|
if (res.code === 200) { // 新增成功
|
||||||
this.getBrandList().then(res2 => { // 新增成功后,重新调用getBrandList,刷新brandList
|
this.getBrandList().then(res2 => { // 新增成功后,重新调用getBrandList,刷新brandList
|
||||||
const newBrand = this.brandList.find(b => b.name === this.editModel.brandId) // 取出刚新增的brand对象
|
const newBrand = this.brandList.find(b => b.name === this.editModel.brandId) // 取出刚新增的brand对象
|
||||||
@@ -168,10 +168,9 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.saveModel()
|
this.saveModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
selectWalk (walk) {
|
selectWalk (walk) {
|
||||||
console.log(walk);
|
console.log(walk)
|
||||||
if (this.editModule.walk.indexOf(walk) != -1) {
|
if (this.editModule.walk.indexOf(walk) != -1) {
|
||||||
this.editModule.walk.splice(this.editModule.walk.indexOf(walk), 1)
|
this.editModule.walk.splice(this.editModule.walk.indexOf(walk), 1)
|
||||||
} else {
|
} else {
|
||||||
@@ -191,8 +190,8 @@ export default {
|
|||||||
},
|
},
|
||||||
/* 获取chart列表数据 */
|
/* 获取chart列表数据 */
|
||||||
ChartTemplateList () {
|
ChartTemplateList () {
|
||||||
this.$get('visual/panel/chart',{pageSize : -1 , varType : 1, panelId: 0}).then(res => {
|
this.$get('visual/panel/chart', { pageSize: -1, varType: 1, panelId: 0 }).then(res => {
|
||||||
console.log(res);
|
console.log(res)
|
||||||
this.chartlList = res.data.list
|
this.chartlList = res.data.list
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@
|
|||||||
<!--password-->
|
<!--password-->
|
||||||
<el-form-item :label="$t('config.user.pin')" prop="pin">
|
<el-form-item :label="$t('config.user.pin')" prop="pin">
|
||||||
<el-input id="account-input-password" v-model="editUser.pin" maxlength="16" placeholder=""
|
<el-input id="account-input-password" v-model="editUser.pin" maxlength="16" placeholder=""
|
||||||
show-word-limit size="small" type="password" @blur="passwordBlur"></el-input>
|
show-word-limit size="small" type="password" @blur="pinBlur"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--passwordChange-->
|
<!--pinChange-->
|
||||||
<el-form-item :label="$t('config.user.confirmPwd')" label-width="200px" prop="pinChange">
|
<el-form-item :label="$t('config.user.confirmPin')" label-width="200px" prop="pinChange">
|
||||||
<el-input id="account-input-passwordChange" v-model="editUser.pinChange" maxlength="16" placeholder=""
|
<el-input id="account-input-pinChange" v-model="editUser.pinChange" maxlength="16" placeholder=""
|
||||||
show-word-limit size="small" type="password"></el-input>
|
show-word-limit size="small" type="password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--email-->
|
<!--email-->
|
||||||
@@ -90,11 +90,11 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
const vm = this
|
const vm = this
|
||||||
const validatePassword = (rule, value, callback) => { // 确认密码的二次校验
|
const validatePin = (rule, value, callback) => { // 确认密码的二次校验
|
||||||
if (value === '' && this.editUser.pin) {
|
if (value === '' && this.editUser.pin) {
|
||||||
callback(new Error(this.$t('config.user.inputConfirmPwd')))
|
callback(new Error(this.$t('config.user.inputConfirmPin')))
|
||||||
} else if (value !== this.editUser.pin) {
|
} else if (value !== this.editUser.pin) {
|
||||||
callback(new Error(this.$t('config.user.confirmPwdErr')))
|
callback(new Error(this.$t('config.user.confirmPinErr')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ export default {
|
|||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
pinChange: [
|
pinChange: [
|
||||||
{ validator: validatePassword, trigger: 'blur' },
|
{ validator: validatePin, trigger: 'blur' },
|
||||||
{ required: true, message: '', trigger: 'blur' }
|
{ required: true, message: '', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
roleIds: [
|
roleIds: [
|
||||||
@@ -129,7 +129,7 @@ export default {
|
|||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
pinChange: [
|
pinChange: [
|
||||||
{ validator: validatePassword, trigger: 'blur' }
|
{ validator: validatePin, trigger: 'blur' }
|
||||||
],
|
],
|
||||||
roleIds: [
|
roleIds: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
@@ -166,9 +166,9 @@ export default {
|
|||||||
this.$emit('close', refresh)
|
this.$emit('close', refresh)
|
||||||
},
|
},
|
||||||
/* 密码失去焦点 检验确认密码 */
|
/* 密码失去焦点 检验确认密码 */
|
||||||
passwordBlur () {
|
pinBlur () {
|
||||||
if (this.editUser.pin && this.editUser.pinChange) {
|
if (this.editUser.pin && this.editUser.pinChange) {
|
||||||
this.$refs.accountForm.validateField('passwordChange')
|
this.$refs.accountForm.validateField('pinChange')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getRoles () {
|
getRoles () {
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
agent2: agent2,
|
agent2: agent2,
|
||||||
|
agentPrometheusEnabled: localStorage.getItem('nz-prometheus-federation-enabled'),
|
||||||
rules: {
|
rules: {
|
||||||
'dc.name': [
|
'dc.name': [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||||
|
|||||||
@@ -395,10 +395,10 @@ export default {
|
|||||||
port: 22,
|
port: 22,
|
||||||
params: {
|
params: {
|
||||||
user: '',
|
user: '',
|
||||||
method: 'password',
|
method: 'pin',
|
||||||
password: '',
|
pin: '',
|
||||||
key: '',
|
key: '',
|
||||||
keyPassword: ''
|
keyPin: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if (type == 'TELNET') {
|
} else if (type == 'TELNET') {
|
||||||
@@ -407,9 +407,9 @@ export default {
|
|||||||
port: 23,
|
port: 23,
|
||||||
params: {
|
params: {
|
||||||
user: '',
|
user: '',
|
||||||
password: '',
|
pin: '',
|
||||||
userTip: '',
|
userTip: '',
|
||||||
passwordTip: '',
|
pinTip: '',
|
||||||
reloginTip: ''
|
reloginTip: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -422,8 +422,8 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
securityName: '',
|
securityName: '',
|
||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
password: '',
|
pin: '',
|
||||||
privPassword: '',
|
privPin: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
contextName: ''
|
contextName: ''
|
||||||
|
|||||||
@@ -544,10 +544,10 @@ export default {
|
|||||||
port: 22,
|
port: 22,
|
||||||
params: {
|
params: {
|
||||||
user: '',
|
user: '',
|
||||||
method: 'password',
|
method: 'pin',
|
||||||
password: '',
|
pin: '',
|
||||||
key: '',
|
key: '',
|
||||||
passwordKey: ''
|
pinKey: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if (type == 'TELNET') {
|
} else if (type == 'TELNET') {
|
||||||
@@ -556,9 +556,9 @@ export default {
|
|||||||
port: 23,
|
port: 23,
|
||||||
params: {
|
params: {
|
||||||
user: '',
|
user: '',
|
||||||
password: '',
|
pin: '',
|
||||||
userTip: '',
|
userTip: '',
|
||||||
passwordTip: '',
|
pinTip: '',
|
||||||
reloginTip: ''
|
reloginTip: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -571,8 +571,8 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
securityName: '',
|
securityName: '',
|
||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
password: '',
|
pin: '',
|
||||||
privPassword: '',
|
privPin: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
contextName: ''
|
contextName: ''
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ export default {
|
|||||||
labelModule: [],
|
labelModule: [],
|
||||||
basic_auth: {
|
basic_auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
pin: ''
|
||||||
},
|
},
|
||||||
bearer_token: ''
|
bearer_token: ''
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export default {
|
|||||||
editDc: {},
|
editDc: {},
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
state: [
|
state: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--host-->
|
<!--host-->
|
||||||
<el-form-item :label='$t("project.endpoint.host")' prop="host">
|
<el-form-item :label='$t("project.endpoint.host")' prop="host">
|
||||||
<el-input placeholder="" v-model.number="editEndpoint.configs.host" size="small" id="module-box-input-host"></el-input>
|
<el-input placeholder="" v-model="editEndpoint.configs.host" size="small" id="module-box-input-host"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<transition name="el-zoom-in-top">
|
<transition name="el-zoom-in-top">
|
||||||
<div v-show="showAllBasicOption" >
|
<div v-show="showAllBasicOption" >
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label='$t("project.endpoint.pin")' prop="authtype" v-if="authType === 1" class="half-form-item">
|
<el-form-item :label='$t("project.endpoint.pin")' prop="authtype" v-if="authType === 1" class="half-form-item">
|
||||||
<el-input placeholder='' v-model.number="editEndpoint.configs.basic_auth.password" size="small" id="module-box-input-password"></el-input>
|
<el-input placeholder='' v-model.number="editEndpoint.configs.basic_auth.pin" size="small" id="module-box-input-password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!--authtype 2-->
|
<!--authtype 2-->
|
||||||
@@ -454,7 +454,7 @@ export default {
|
|||||||
params.configs = JSON.stringify(params.configs)
|
params.configs = JSON.stringify(params.configs)
|
||||||
if (this.authType === 2 && !this.editEndpoint.configs.bearer_token) {
|
if (this.authType === 2 && !this.editEndpoint.configs.bearer_token) {
|
||||||
this.$message.error("'token' is required")
|
this.$message.error("'token' is required")
|
||||||
} else if (this.authType === 1 && !(this.editEndpoint.configs.basic_auth.username && this.editEndpoint.configs.basic_auth.password)) {
|
} else if (this.authType === 1 && !(this.editEndpoint.configs.basic_auth.username && this.editEndpoint.configs.basic_auth.pin)) {
|
||||||
this.$message.error("'username' and 'password' is required")
|
this.$message.error("'username' and 'password' is required")
|
||||||
} else {
|
} else {
|
||||||
this.authType = 0
|
this.authType = 0
|
||||||
@@ -608,7 +608,7 @@ export default {
|
|||||||
this.editEndpoint.configs.bearer_token = ''
|
this.editEndpoint.configs.bearer_token = ''
|
||||||
this.editEndpoint.configs.basic_auth = {
|
this.editEndpoint.configs.basic_auth = {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
pin: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
copyValue () {
|
copyValue () {
|
||||||
@@ -717,7 +717,7 @@ export default {
|
|||||||
if (params.basic_auth && !params.basic_auth.username) {
|
if (params.basic_auth && !params.basic_auth.username) {
|
||||||
delete params.basic_auth
|
delete params.basic_auth
|
||||||
}
|
}
|
||||||
if (params.basic_auth && !params.basic_auth.password) {
|
if (params.basic_auth && !params.basic_auth.pin) {
|
||||||
delete params.basic_auth
|
delete params.basic_auth
|
||||||
}
|
}
|
||||||
if (params.param && !Object.keys(params.param).length) {
|
if (params.param && !Object.keys(params.param).length) {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--host-->
|
<!--host-->
|
||||||
<el-form-item :label='$t("project.endpoint.host")' prop="host">
|
<el-form-item :label='$t("project.endpoint.host")' prop="host">
|
||||||
<el-input placeholder="" v-model.number="editModule.configs.host" size="small" id="module-box-input-host"></el-input>
|
<el-input placeholder="" v-model="editModule.configs.host" size="small" id="module-box-input-host"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<transition name="el-zoom-in-top">
|
<transition name="el-zoom-in-top">
|
||||||
<div v-show="showAllBasicOption" >
|
<div v-show="showAllBasicOption" >
|
||||||
@@ -292,10 +292,10 @@ export default {
|
|||||||
username: [
|
username: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
password: [
|
pin: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
priv_password: [
|
priv_pin: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
max_repetitions: [
|
max_repetitions: [
|
||||||
@@ -448,7 +448,7 @@ export default {
|
|||||||
params.configs = JSON.stringify(params.configs)
|
params.configs = JSON.stringify(params.configs)
|
||||||
if (this.authType === 2 && !this.editModule.configs.bearer_token) {
|
if (this.authType === 2 && !this.editModule.configs.bearer_token) {
|
||||||
this.$message.error("'token' is required")
|
this.$message.error("'token' is required")
|
||||||
} else if (this.authType === 1 && !(this.editModule.configs.basic_auth.username && this.editModule.configs.basic_auth.password)) {
|
} else if (this.authType === 1 && !(this.editModule.configs.basic_auth.username && this.editModule.configs.basic_auth.pin)) {
|
||||||
this.$message.error("'username' and 'password' is required")
|
this.$message.error("'username' and 'password' is required")
|
||||||
} else {
|
} else {
|
||||||
this.authType = 0
|
this.authType = 0
|
||||||
@@ -588,7 +588,7 @@ export default {
|
|||||||
this.editModule.configs.bearer_token = ''
|
this.editModule.configs.bearer_token = ''
|
||||||
this.editModule.configs.basic_auth = {
|
this.editModule.configs.basic_auth = {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
pin: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
copyValue () {
|
copyValue () {
|
||||||
@@ -696,7 +696,7 @@ export default {
|
|||||||
if (params.basic_auth && !params.basic_auth.username) {
|
if (params.basic_auth && !params.basic_auth.username) {
|
||||||
delete params.basic_auth
|
delete params.basic_auth
|
||||||
}
|
}
|
||||||
if (params.basic_auth && !params.basic_auth.password) {
|
if (params.basic_auth && !params.basic_auth.pin) {
|
||||||
delete params.basic_auth
|
delete params.basic_auth
|
||||||
}
|
}
|
||||||
if (params.param && !Object.keys(params.param).length) {
|
if (params.param && !Object.keys(params.param).length) {
|
||||||
|
|||||||
@@ -36,101 +36,101 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "cabinetBox",
|
name: 'cabinetBox',
|
||||||
props: {
|
props: {
|
||||||
obj: { type: Object },
|
obj: { type: Object },
|
||||||
currentDc: { type: Object }
|
currentDc: { type: Object }
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
editCabinet: {},
|
editCabinet: {},
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
uSize: [
|
uSize: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
||||||
{ type: 'number', min: 1, max: 47, message: this.$t('validate.uSize'), trigger: 'blur' }
|
{ type: 'number', min: 1, max: 47, message: this.$t('validate.uSize'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clickOutside () {
|
||||||
|
this.esc(false)
|
||||||
},
|
},
|
||||||
methods: {
|
esc (refresh) {
|
||||||
clickOutside () {
|
this.prevent_opt.save = false
|
||||||
this.esc(false)
|
this.$emit('close', refresh)
|
||||||
},
|
},
|
||||||
esc (refresh) {
|
save () {
|
||||||
this.prevent_opt.save = false
|
if (this.prevent_opt.save) { return } ;
|
||||||
this.$emit('close', refresh)
|
this.prevent_opt.save = true
|
||||||
},
|
this.$refs.cabinetForm.validate(valid => {
|
||||||
save () {
|
if (valid) {
|
||||||
if (this.prevent_opt.save) { return } ;
|
this.editCabinet.idcId = this.currentDc.id
|
||||||
this.prevent_opt.save = true
|
if (this.editCabinet.id) {
|
||||||
this.$refs.cabinetForm.validate(valid => {
|
this.$put('cabinet', this.editCabinet).then(res => {
|
||||||
if (valid) {
|
this.prevent_opt.save = false
|
||||||
this.editCabinet.idcId = this.currentDc.id
|
if (res.code === 200) {
|
||||||
if (this.editCabinet.id) {
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
this.$put('cabinet', this.editCabinet).then(res => {
|
this.esc(true)
|
||||||
this.prevent_opt.save = false
|
} else {
|
||||||
if (res.code === 200) {
|
this.$message.error(res.msg)
|
||||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
}
|
||||||
this.esc(true)
|
})
|
||||||
} else {
|
|
||||||
this.$message.error(res.msg)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$post('cabinet', this.editCabinet).then(res => {
|
|
||||||
this.prevent_opt.save = false
|
|
||||||
if (res.code === 200) {
|
|
||||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
|
||||||
this.esc(true)
|
|
||||||
} else {
|
|
||||||
this.$message.error(res.msg)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.prevent_opt.save = false
|
this.$post('cabinet', this.editCabinet).then(res => {
|
||||||
return false
|
this.prevent_opt.save = false
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
this.esc(true)
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
} else {
|
||||||
},
|
|
||||||
del () {
|
|
||||||
if (this.prevent_opt.save) { return } ;
|
|
||||||
this.prevent_opt.save = true
|
|
||||||
this.$confirm(this.$t('tip.confirmDelete'), {
|
|
||||||
confirmButtonText: this.$t('tip.yes'),
|
|
||||||
cancelButtonText: this.$t('tip.no'),
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
|
||||||
this.$delete('/cabinet?ids=' + this.editCabinet.id).then(response => {
|
|
||||||
this.prevent_opt.save = false
|
|
||||||
if (response.code == 200) {
|
|
||||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
|
||||||
this.esc(true)
|
|
||||||
} else {
|
|
||||||
this.$message.error(response.msg)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).catch(() => {
|
|
||||||
this.prevent_opt.save = false
|
this.prevent_opt.save = false
|
||||||
})
|
return false
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
del () {
|
||||||
obj: {
|
if (this.prevent_opt.save) { return } ;
|
||||||
deep: true,
|
this.prevent_opt.save = true
|
||||||
immediate: true,
|
this.$confirm(this.$t('tip.confirmDelete'), {
|
||||||
handler: function (n, o) {
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
if (n) {
|
cancelButtonText: this.$t('tip.no'),
|
||||||
this.editCabinet = JSON.parse(JSON.stringify(n))
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.$delete('/cabinet?ids=' + this.editCabinet.id).then(response => {
|
||||||
|
this.prevent_opt.save = false
|
||||||
|
if (response.code == 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
this.esc(true)
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.msg)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
this.prevent_opt.save = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
obj: {
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
handler: function (n, o) {
|
||||||
|
if (n) {
|
||||||
|
this.editCabinet = JSON.parse(JSON.stringify(n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default {
|
|||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
},
|
},
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
},
|
},
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@ export default {
|
|||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
},
|
},
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
@@ -240,7 +240,7 @@ export default {
|
|||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configs.forEach(item => {
|
configs.forEach(item => {
|
||||||
@@ -269,7 +269,7 @@ export default {
|
|||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
},
|
},
|
||||||
configs: [
|
configs: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
<div class="mib-browser-ad-search-label">{{$t('login.pin')}}</div>
|
<div class="mib-browser-ad-search-label">{{$t('login.pin')}}</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="17">
|
<el-col :span="17">
|
||||||
<el-input class="input-x-mini-24" v-model.trim="assetSetting.auth.password" id="traffic-setting-password"></el-input>
|
<el-input class="input-x-mini-24" v-model.trim="assetSetting.auth.pin" id="traffic-setting-password"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -101,10 +101,10 @@
|
|||||||
|
|
||||||
<el-row class="mib-browser-ad-search-item" v-if="assetSetting.auth.securityLevel == 'authPriv'">
|
<el-row class="mib-browser-ad-search-item" v-if="assetSetting.auth.securityLevel == 'authPriv'">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<div class="mib-browser-ad-search-label">{{$t('project.module.privPassword')}}</div>
|
<div class="mib-browser-ad-search-label">{{$t('project.module.privPin')}}</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="17">
|
<el-col :span="17">
|
||||||
<el-input class="input-x-mini-24" v-model.trim="assetSetting.auth.privPassword" id="traffic-setting-privPassword"></el-input>
|
<el-input class="input-x-mini-24" v-model.trim="assetSetting.auth.privPin" id="traffic-setting-privPassword"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -26,11 +26,11 @@
|
|||||||
<!--password-->
|
<!--password-->
|
||||||
<el-form-item :label="$t('config.account.pin')" prop="pin">
|
<el-form-item :label="$t('config.account.pin')" prop="pin">
|
||||||
<el-input id="account-input-password" v-model="editUser.pin" autocomplete="new-password" maxlength="16" placeholder=""
|
<el-input id="account-input-password" v-model="editUser.pin" autocomplete="new-password" maxlength="16" placeholder=""
|
||||||
show-word-limit size="small" type="password" @blur="passwordBlur"></el-input>
|
show-word-limit size="small" type="password" @blur="pinBlur"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--passwordChange-->
|
<!--pinChange-->
|
||||||
<el-form-item :label="$t('config.account.confirmPwd')" label-width="200px" prop="passwordChange">
|
<el-form-item :label="$t('config.account.confirmPin')" label-width="200px" prop="pinChange">
|
||||||
<el-input id="account-input-passwordChange" v-model="editUser.pinChange" autocomplete="new-password" maxlength="16" placeholder=""
|
<el-input id="account-input-pinChange" v-model="editUser.pinChange" autocomplete="new-password" maxlength="16" placeholder=""
|
||||||
show-word-limit size="small" type="password"></el-input>
|
show-word-limit size="small" type="password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--email-->
|
<!--email-->
|
||||||
@@ -109,11 +109,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
const validatePassword = (rule, value, callback) => { // 确认密码的二次校验
|
const validatepin = (rule, value, callback) => { // 确认密码的二次校验
|
||||||
if (value === '' && this.editUser.pin) {
|
if (value === '' && this.editUser.pin) {
|
||||||
callback(new Error(this.$t('config.account.inputConfirmPwd')))
|
callback(new Error(this.$t('config.account.inputConfirmPin')))
|
||||||
} else if (value !== this.editUser.pin) {
|
} else if (value !== this.editUser.pin) {
|
||||||
callback(new Error(this.$t('config.account.confirmPwdErr')))
|
callback(new Error(this.$t('config.account.confirmPinErr')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ export default {
|
|||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
pinChange: [
|
pinChange: [
|
||||||
{ validator: validatePassword, trigger: 'blur' },
|
{ validator: validatepin, trigger: 'blur' },
|
||||||
{ required: true, message: '', trigger: 'blur' }
|
{ required: true, message: '', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
roleIds: [
|
roleIds: [
|
||||||
@@ -143,7 +143,7 @@ export default {
|
|||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
pinChange: [
|
pinChange: [
|
||||||
{ validator: validatePassword, trigger: 'blur' }
|
{ validator: validatepin, trigger: 'blur' }
|
||||||
],
|
],
|
||||||
roleIds: [
|
roleIds: [
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
@@ -228,9 +228,9 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
/* 密码失去焦点 检验确认密码 */
|
/* 密码失去焦点 检验确认密码 */
|
||||||
passwordBlur () {
|
pinBlur () {
|
||||||
if (this.editUser.pin && this.editUser.pinChange) {
|
if (this.editUser.pin && this.editUser.pinChange) {
|
||||||
this.$refs.accountForm.validateField('passwordChange')
|
this.$refs.accountForm.validateField('pinChange')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getScripts () {
|
getScripts () {
|
||||||
|
|||||||
@@ -772,7 +772,7 @@ export default {
|
|||||||
objectInfo[val.label] = val.val
|
objectInfo[val.label] = val.val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('search obj',objectInfo)
|
console.log('search obj', objectInfo)
|
||||||
})
|
})
|
||||||
this.getHeight()
|
this.getHeight()
|
||||||
// 搜索完成后存储在本地历史记录中
|
// 搜索完成后存储在本地历史记录中
|
||||||
|
|||||||
@@ -142,23 +142,23 @@ const searchSelectInfo = { // value: 传给后台的值;label:显示给用
|
|||||||
label: i18n.t('overall.result.failed')
|
label: i18n.t('overall.result.failed')
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
terminalStatus:[
|
terminalStatus: [
|
||||||
{
|
{
|
||||||
value: 0,
|
value: 0,
|
||||||
label: i18n.t('config.terminallog.statusItem.connecting')
|
label: i18n.t('config.terminallog.statusItem.connecting')
|
||||||
},{
|
}, {
|
||||||
value: 1,
|
value: 1,
|
||||||
label: i18n.t('config.terminallog.statusItem.connectionFailed')
|
label: i18n.t('config.terminallog.statusItem.connectionFailed')
|
||||||
},{
|
}, {
|
||||||
value: 2,
|
value: 2,
|
||||||
label: i18n.t('config.terminallog.statusItem.over')
|
label: i18n.t('config.terminallog.statusItem.over')
|
||||||
},{
|
}, {
|
||||||
value: 3,
|
value: 3,
|
||||||
label: i18n.t('config.terminallog.statusItem.kickedOut')
|
label: i18n.t('config.terminallog.statusItem.kickedOut')
|
||||||
},{
|
}, {
|
||||||
value: 4,
|
value: 4,
|
||||||
label: i18n.t('config.terminallog.statusItem.unknownError')
|
label: i18n.t('config.terminallog.statusItem.unknownError')
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
export default searchSelectInfo
|
export default searchSelectInfo
|
||||||
|
|||||||
@@ -77,54 +77,54 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import table from '@/components/common/mixin/table'
|
import table from '@/components/common/mixin/table'
|
||||||
export default {
|
export default {
|
||||||
name: "cabinet Table",
|
name: 'cabinet Table',
|
||||||
mixins: [table],
|
mixins: [table],
|
||||||
data(){
|
data () {
|
||||||
return{
|
return {
|
||||||
tableTitle: [
|
tableTitle: [
|
||||||
{
|
{
|
||||||
label: 'ID',
|
label: 'ID',
|
||||||
prop: 'id',
|
prop: 'id',
|
||||||
show: true,
|
show: true,
|
||||||
width: 80
|
width: 80
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('overall.name'),
|
label: this.$t('overall.name'),
|
||||||
prop: 'name',
|
prop: 'name',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('asset.uSize'),
|
label: this.$t('asset.uSize'),
|
||||||
prop: 'uSize',
|
prop: 'uSize',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('config.dc.assets'),
|
label: this.$t('config.dc.assets'),
|
||||||
prop: 'assetStat',
|
prop: 'assetStat',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('alert.alert'),
|
label: this.$t('alert.alert'),
|
||||||
prop: 'alertStat',
|
prop: 'alertStat',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('config.dc.remark'),
|
label: this.$t('config.dc.remark'),
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('config.account.option'),
|
label: this.$t('config.account.option'),
|
||||||
prop: 'option',
|
prop: 'option',
|
||||||
show: true,
|
show: true,
|
||||||
width: 120
|
width: 120
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export default {
|
|||||||
name: this.$t('dashboard.panel.chartForm.typeVal.group.label')
|
name: this.$t('dashboard.panel.chartForm.typeVal.group.label')
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -144,37 +144,37 @@ export default {
|
|||||||
let str = 'nz-icon '
|
let str = 'nz-icon '
|
||||||
switch (row.type) {
|
switch (row.type) {
|
||||||
case 'line':
|
case 'line':
|
||||||
str += 'nz-icon-LinkChart'
|
str += 'nz-icon-link-chart'
|
||||||
break
|
break
|
||||||
case 'bar':
|
case 'bar':
|
||||||
str += 'nz-icon-barchart'
|
str += 'nz-icon-bar-chart'
|
||||||
break
|
break
|
||||||
case 'stackArea':
|
case 'stackArea':
|
||||||
str += 'nz-icon-StackArea'
|
str += 'nz-icon-stack-area'
|
||||||
break
|
break
|
||||||
case 'singleStat':
|
case 'singleStat':
|
||||||
str += 'nz-icon-SingleValue'
|
str += 'nz-icon-single-value'
|
||||||
break
|
break
|
||||||
case 'pie':
|
case 'pie':
|
||||||
str += 'nz-icon-Piechart'
|
str += 'nz-icon-pie-chart'
|
||||||
break
|
break
|
||||||
case 'table':
|
case 'table':
|
||||||
str += 'nz-icon-Table1'
|
str += 'nz-icon-table1'
|
||||||
break
|
break
|
||||||
case 'alertList':
|
case 'alertList':
|
||||||
str += 'nz-icon-alertlist'
|
str += 'nz-icon-alert-list'
|
||||||
break
|
break
|
||||||
case 'text':
|
case 'text':
|
||||||
str += 'nz-icon-Text1'
|
str += 'nz-icon-text1'
|
||||||
break
|
break
|
||||||
case 'url':
|
case 'url':
|
||||||
str += 'nz-icon-URL'
|
str += 'nz-icon-url'
|
||||||
break
|
break
|
||||||
case 'group':
|
case 'group':
|
||||||
str += 'nz-icon-Group'
|
str += 'nz-icon-group'
|
||||||
break
|
break
|
||||||
default :
|
default :
|
||||||
str += 'nz-icon-Table1'
|
str += 'nz-icon-table1'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export default {
|
|||||||
label: this.$t('config.dc.assets'),
|
label: this.$t('config.dc.assets'),
|
||||||
prop: 'assetNum',
|
prop: 'assetNum',
|
||||||
show: true
|
show: true
|
||||||
},{
|
}, {
|
||||||
label: this.$t('config.dc.alert'),
|
label: this.$t('config.dc.alert'),
|
||||||
prop: 'alertNum',
|
prop: 'alertNum',
|
||||||
show: true
|
show: true
|
||||||
@@ -162,7 +162,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showTableTooltip, hideTableTooltip,
|
showTableTooltip,
|
||||||
|
hideTableTooltip,
|
||||||
regNumTest (val) { // 校验是否是数字
|
regNumTest (val) { // 校验是否是数字
|
||||||
return this.regNum.test(val)
|
return this.regNum.test(val)
|
||||||
},
|
},
|
||||||
@@ -186,7 +187,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
<div v-else-if="scope.row[item.prop]===1">
|
<div v-else-if="scope.row[item.prop]===1">
|
||||||
<div class="active-icon green inline-block"></div> up
|
<div class="active-icon green inline-block"></div> up
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else-if="scope.row[item.prop]">
|
||||||
<div class="active-icon gray inline-block"></div> suspended
|
<div class="active-icon gray inline-block"></div> suspended
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -174,6 +174,7 @@ export default {
|
|||||||
this.$message.success(this.$t('overall.copySuccess'))
|
this.$message.success(this.$t('overall.copySuccess'))
|
||||||
},
|
},
|
||||||
suspendedStr (status) { // 10进制转为2进制 分别给对应的状态
|
suspendedStr (status) { // 10进制转为2进制 分别给对应的状态
|
||||||
|
if (!status || status === 1 || status == 0) { return '' }
|
||||||
const arr = status.toString(2).split('')
|
const arr = status.toString(2).split('')
|
||||||
while (arr.length < 5) {
|
while (arr.length < 5) {
|
||||||
arr.unshift('0')
|
arr.unshift('0')
|
||||||
|
|||||||
@@ -95,11 +95,11 @@ export default {
|
|||||||
label: this.$t('config.model.remark'),
|
label: this.$t('config.model.remark'),
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
show: true
|
show: true
|
||||||
},{
|
}, {
|
||||||
label: this.$t('config.model.assetNum'),
|
label: this.$t('config.model.assetNum'),
|
||||||
prop: 'assetNum',
|
prop: 'assetNum',
|
||||||
show: true,
|
show: true,
|
||||||
width:200
|
width: 200
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'authType'">
|
<template v-else-if="item.prop === 'authType'">
|
||||||
<span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
|
<span v-if="scope.row.authType == 1">{{$t('config.terminallog.pin')}}</span>
|
||||||
<span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
|
<span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{scope.row[item.prop]}}</span>
|
<span v-else>{{scope.row[item.prop]}}</span>
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ export default {
|
|||||||
this.graphShow = false
|
this.graphShow = false
|
||||||
},
|
},
|
||||||
saveChart () { // 新增chart
|
saveChart () { // 新增chart
|
||||||
this.getPanelData().then(()=>{
|
this.getPanelData().then(() => {
|
||||||
const chart = {
|
const chart = {
|
||||||
title: '',
|
title: '',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<el-dropdown >
|
<el-dropdown>
|
||||||
|
<el-dropdown-menu slot="dropdown"></el-dropdown-menu>
|
||||||
<div id="header-open-cli" @click="cli">
|
<div id="header-open-cli" @click="cli">
|
||||||
<div class="header-menu--item"><i class="nz-icon nz-icon-terminal"></i></div>
|
<div class="header-menu--item"><i class="nz-icon nz-icon-terminal"></i></div>
|
||||||
<span v-show="$store.state.consoleCount>0" class="right-tip">{{$store.state.consoleCount<=10?$store.state.consoleCount:'10+'}}</span>
|
<span v-show="$store.state.consoleCount>0" class="right-tip">{{$store.state.consoleCount<=10?$store.state.consoleCount:'10+'}}</span>
|
||||||
@@ -48,7 +49,7 @@
|
|||||||
<div class='login-user header-menu--item'>{{username}} <i class="nz-icon nz-icon-arrow-down"></i></div>
|
<div class='login-user header-menu--item'>{{username}} <i class="nz-icon nz-icon-arrow-down"></i></div>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
<div id="header-to-changepwd" @click="showPwdDialog">{{$t('overall.changePwd')}}</div>
|
<div id="header-to-changepin" @click="showPinDialog">{{$t('overall.changePin')}}</div>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
<div id="header-to-logout" @click="logout">{{$t('overall.signOut')}}</div>
|
<div id="header-to-logout" @click="logout">{{$t('overall.signOut')}}</div>
|
||||||
@@ -74,7 +75,7 @@
|
|||||||
<transition name="right-box">
|
<transition name="right-box">
|
||||||
<dc-box v-if="rightBox.dc.show" :dc="dc" :user-data="userData" @close="closeDcBox" @reload="getAssetData"></dc-box>
|
<dc-box v-if="rightBox.dc.show" :dc="dc" :user-data="userData" @close="closeDcBox" @reload="getAssetData"></dc-box>
|
||||||
</transition>
|
</transition>
|
||||||
<change-password :cur-user="username" :show-dialog="showChangePwd" @click="showPwdDialog" @dialogClosed="dialogClosed"></change-password>
|
<change-password :cur-user="username" :show-dialog="showChangePin" @click="showPinDialog" @dialogClosed="dialogClosed"></change-password>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -82,11 +83,11 @@
|
|||||||
import bus from '../../libs/bus'
|
import bus from '../../libs/bus'
|
||||||
import dcBox from '../common/rightBox/dcBox' // dc弹框
|
import dcBox from '../common/rightBox/dcBox' // dc弹框
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex'
|
||||||
import changePwd from '../page/config/changePwd'
|
import changePin from '../page/config/changePin'
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
components: {
|
components: {
|
||||||
'change-password': changePwd,
|
'change-password': changePin,
|
||||||
'dc-box': dcBox
|
'dc-box': dcBox
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -202,7 +203,7 @@ export default {
|
|||||||
permission: 'header_add_rule'
|
permission: 'header_add_rule'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
showChangePwd: false
|
showChangePin: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -257,10 +258,10 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
username: '',
|
username: '',
|
||||||
security_level: 'noAuthNoPriv', // noAuthNoPriv/authNoPriv/authPriv
|
security_level: 'noAuthNoPriv', // noAuthNoPriv/authNoPriv/authPriv
|
||||||
password: '',
|
pin: '',
|
||||||
auth_protocol: 'MD5', // MD5/SHA
|
auth_protocol: 'MD5', // MD5/SHA
|
||||||
priv_protocol: 'DES', // DES/AES
|
priv_protocol: 'DES', // DES/AES
|
||||||
priv_password: '',
|
priv_pin: '',
|
||||||
context_name: ''
|
context_name: ''
|
||||||
}
|
}
|
||||||
} else if (item.type == 3) {
|
} else if (item.type == 3) {
|
||||||
@@ -402,11 +403,11 @@ export default {
|
|||||||
window.location.reload()
|
window.location.reload()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
showPwdDialog () {
|
showPinDialog () {
|
||||||
this.showChangePwd = true
|
this.showChangePin = true
|
||||||
},
|
},
|
||||||
dialogClosed () {
|
dialogClosed () {
|
||||||
this.showChangePwd = false
|
this.showChangePin = false
|
||||||
},
|
},
|
||||||
cancel () {
|
cancel () {
|
||||||
this.jumpTo(this.$route.path.slice(1, this.$route.path.length))
|
this.jumpTo(this.$route.path.slice(1, this.$route.path.length))
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.pin')" v-if="account.params.method == 'password'">
|
<el-form-item :label="$t('asset.pin')" v-if="account.params.method == 'password'">
|
||||||
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.password" id="ssh-account-password"/>
|
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.pin" id="ssh-account-password"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.ssh')" v-if="account.params.method == 'key'" prop="file">
|
<el-form-item :label="$t('asset.ssh')" v-if="account.params.method == 'key'" prop="file">
|
||||||
<el-input rows="4" type="textarea" placeholder="" v-model="account.params.key" size="small" id="ssh-account-key"></el-input>
|
<el-input rows="4" type="textarea" placeholder="" v-model="account.params.key" size="small" id="ssh-account-key"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.pin')" v-if="account.params.method == 'key'">
|
<el-form-item :label="$t('asset.pin')" v-if="account.params.method == 'key'">
|
||||||
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.keyPassword" id="ssh-account-keyPassword"/>
|
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.keyPin" id="ssh-account-keyPin"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.port')" prop="port" style="display: inline-block">
|
<el-form-item :label="$t('asset.port')" prop="port" style="display: inline-block">
|
||||||
<el-input size="small" v-model.number="account.port" id="ssh-account-port"/>
|
<el-input size="small" v-model.number="account.port" id="ssh-account-port"/>
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
<el-input autocomplete="new-password" size="small" v-model="account.params.userTip" id="telnet-account-userTip"/>
|
<el-input autocomplete="new-password" size="small" v-model="account.params.userTip" id="telnet-account-userTip"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.pin')">
|
<el-form-item :label="$t('asset.pin')">
|
||||||
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.password" id="telnet-account-password"/>
|
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.pin" id="telnet-account-pin"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="this.$t('asset.pinTip')">
|
<el-form-item :label="this.$t('asset.pinTip')">
|
||||||
<el-input size="small" v-model="account.params.passwordTip" id="telnet-account-passwordTip"/>
|
<el-input size="small" v-model="account.params.pinTip" id="telnet-account-pinTip"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.reloginpinTip')" prop="reloginTip">
|
<el-form-item :label="$t('asset.reloginPinTip')" prop="reloginTip">
|
||||||
<el-input size="small" v-model="account.params.reloginTip" id="telnet-account-reloginTip"/>
|
<el-input size="small" v-model="account.params.reloginTip" id="telnet-account-reloginTip"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('asset.port')" prop="port" style="display: inline-block">
|
<el-form-item :label="$t('asset.port')" prop="port" style="display: inline-block">
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
<el-radio-button label="authPriv"></el-radio-button>
|
<el-radio-button label="authPriv"></el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('login.pin')" prop="params.password" v-if="account.params.securityLevel == 'authNoPriv' || account.params.securityLevel == 'authPriv'">
|
<el-form-item :label="$t('login.pin')" prop="params.pin" v-if="account.params.securityLevel == 'authNoPriv' || account.params.securityLevel == 'authPriv'">
|
||||||
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.password" id="snmp-account-password"/>
|
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.pin" id="snmp-account-password"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('project.module.authProtocol')" prop="params.authProtocol" v-if="account.params.securityLevel == 'authNoPriv' || account.params.securityLevel == 'authPriv'">
|
<el-form-item :label="$t('project.module.authProtocol')" prop="params.authProtocol" v-if="account.params.securityLevel == 'authNoPriv' || account.params.securityLevel == 'authPriv'">
|
||||||
<el-radio-group v-model="account.params.authProtocol" size="small" id="snmp-account-authProtocol">
|
<el-radio-group v-model="account.params.authProtocol" size="small" id="snmp-account-authProtocol">
|
||||||
@@ -86,8 +86,8 @@
|
|||||||
<el-radio-button label="AES"></el-radio-button>
|
<el-radio-button label="AES"></el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('project.module.privpin')" prop="params.privPassword" v-if="account.params.securityLevel == 'authPriv'">
|
<el-form-item :label="$t('project.module.privPin')" prop="params.privPin" v-if="account.params.securityLevel == 'authPriv'">
|
||||||
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.privPassword" id="snmp-account-privPassword"/>
|
<el-input autocomplete="new-password" size="small" type="password" v-model="account.params.privPin" id="snmp-account-privPin"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@@ -123,24 +123,24 @@ export default {
|
|||||||
user: '',
|
user: '',
|
||||||
authType: 1,
|
authType: 1,
|
||||||
protocol: 'SSH',
|
protocol: 'SSH',
|
||||||
pwd: '',
|
pin: '',
|
||||||
port: null,
|
port: null,
|
||||||
privateKey: null,
|
privateKey: null,
|
||||||
userTip: '',
|
userTip: '',
|
||||||
passwordTip: '',
|
pinTip: '',
|
||||||
reloginPasswordTip: ''
|
reloginPinTip: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isShowTelnetOption () {
|
isShowTelnetOption () {
|
||||||
this.showTelnetOption = !this.showTelnetOption
|
this.showTelnetOption = !this.showTelnetOption
|
||||||
if (!this.showTelnetOption) {
|
if (!this.showTelnetOption) {
|
||||||
this.account.userTip = ''
|
this.account.userTip = ''
|
||||||
this.account.passwordTip = ''
|
this.account.pinTip = ''
|
||||||
this.account.reloginPasswordTip = ''
|
this.account.reloginPinTip = ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
telnetOptionState () {
|
telnetOptionState () {
|
||||||
if (this.account.userTip != '' || this.account.passwordTip != '' || this.account.reloginPasswordTip != '') {
|
if (this.account.userTip != '' || this.account.pinTip != '' || this.account.reloginPinTip != '') {
|
||||||
this.showTelnetOption = true
|
this.showTelnetOption = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -155,8 +155,8 @@ export default {
|
|||||||
},
|
},
|
||||||
clearTelnetOptions () {
|
clearTelnetOptions () {
|
||||||
this.account.userTip = ''
|
this.account.userTip = ''
|
||||||
this.account.passwordTip = ''
|
this.account.pinTip = ''
|
||||||
this.account.reloginPasswordTip = ''
|
this.account.reloginPinTip = ''
|
||||||
},
|
},
|
||||||
handleChange (file, fileList) {
|
handleChange (file, fileList) {
|
||||||
if (fileList.length > 0) {
|
if (fileList.length > 0) {
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
this.clearPrivateKey()
|
this.clearPrivateKey()
|
||||||
}
|
}
|
||||||
if (n.authType == 2) { // 公钥登录
|
if (n.authType == 2) { // 公钥登录
|
||||||
this.account.pwd = ''
|
this.account.pin = ''
|
||||||
}
|
}
|
||||||
if (n.protocol == 'SSH') {
|
if (n.protocol == 'SSH') {
|
||||||
this.showTelnetOption = false
|
this.showTelnetOption = false
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog class="nz-dialog" :title="$t('overall.changePwd')" :visible.sync="visible" @open="dialogOpened" :modal-append-to-body='false' @closed="dialogClosed" width="600px" :show-close="false" >
|
<el-dialog class="nz-dialog" :title="$t('overall.changePin')" :visible.sync="visible" @open="dialogOpened" :modal-append-to-body='false' @closed="dialogClosed" width="600px" :show-close="false" >
|
||||||
<el-form :model="user" label-position = "top" label-width="150px" :rules="rules" ref="changePwdForm" size="mini">
|
<el-form :model="user" label-position = "top" label-width="150px" :rules="rules" ref="changePinForm" size="mini">
|
||||||
<el-form-item :label="$t('config.user.account')" prop="username" v-show="curUser != sysUser">
|
<el-form-item :label="$t('config.user.account')" prop="username" v-show="curUser != sysUser">
|
||||||
<el-input type="text" autocomplete="false" v-model="user.username" disabled id="change-pwd-username"></el-input>
|
<el-input type="text" autocomplete="false" v-model="user.username" disabled id="change-pin-username"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.user.oldPwd')" prop="pwd">
|
<el-form-item :label="$t('config.user.oldPin')" prop="pin">
|
||||||
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.pwd" maxlength="20" :placeholder="$t('config.user.inputOldPwd')" id="change-pwd-pwd"></el-input>
|
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.pin" maxlength="20" :placeholder="$t('config.user.inputOldPin')" id="change-pin-pin"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.user.newPwd')" prop="newPwd">
|
<el-form-item :label="$t('config.user.newPin')" prop="newPin">
|
||||||
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.newPwd" maxlength="20" :placeholder="$t('config.user.inputNewPwd')" id="change-pwd-newPwd"></el-input>
|
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.newPin" maxlength="20" :placeholder="$t('config.user.inputNewPin')" id="change-pin-newPin"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.user.confirmPwd')" prop="confirmPwd">
|
<el-form-item :label="$t('config.user.confirmPin')" prop="confirmPin">
|
||||||
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.confirmPwd" maxlength="20" :placeholder="$t('config.user.inputConfirmPwd')" id="change-pwd-confirmPwd"></el-input>
|
<el-input type="password" autocomplete="false" :show-password="true" v-model="user.confirmPin" maxlength="20" :placeholder="$t('config.user.inputConfirmPin')" id="change-pin-confirmPin"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!--底部按钮-->
|
<!--底部按钮-->
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<div class="right-box-bottom-btns" >
|
<div class="right-box-bottom-btns" >
|
||||||
<button @click="close" id="change-pwd-esc"
|
<button @click="close" id="change-pin-esc"
|
||||||
class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
|
class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
|
||||||
<span>{{$t('overall.cancel')}}</span>
|
<span>{{$t('overall.cancel')}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button @click="changePwd" id="change-pwd-save"
|
<button @click="changePin" id="change-pin-save"
|
||||||
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new">
|
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new">
|
||||||
<span>{{$t('overall.save')}}</span>
|
<span>{{$t('overall.save')}}</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'changePwd',
|
name: 'changePin',
|
||||||
props: {
|
props: {
|
||||||
curUser: { type: String },
|
curUser: { type: String },
|
||||||
showDialog: { type: Boolean, default: false }
|
showDialog: { type: Boolean, default: false }
|
||||||
@@ -46,28 +46,28 @@ export default {
|
|||||||
if (value && value != '') {
|
if (value && value != '') {
|
||||||
callback()
|
callback()
|
||||||
} else {
|
} else {
|
||||||
callback(new Error(temp.$t('config.user.invalidPwd')))
|
callback(new Error(temp.$t('config.user.invalidPin')))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const validateConfirmPass = (rule, value, callback) => {
|
const validateConfirmPass = (rule, value, callback) => {
|
||||||
if (value && value != '' && value == temp.user.newPwd) {
|
if (value && value != '' && value == temp.user.newPin) {
|
||||||
callback()
|
callback()
|
||||||
} else {
|
} else {
|
||||||
callback(new Error(temp.$t('config.user.confirmPwdErr')))
|
callback(new Error(temp.$t('config.user.confirmPinErr')))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
user: {
|
user: {
|
||||||
username: '',
|
username: '',
|
||||||
pwd: '',
|
pin: '',
|
||||||
newPwd: '',
|
newPin: '',
|
||||||
confirmPwd: ''
|
confirmPin: ''
|
||||||
},
|
},
|
||||||
sysUser: sessionStorage.getItem('nz-username'),
|
sysUser: sessionStorage.getItem('nz-username'),
|
||||||
rules: {
|
rules: {
|
||||||
pwd: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
pin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
||||||
newPwd: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: validatePass, trigger: 'blur' }],
|
newPin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: validatePass, trigger: 'blur' }],
|
||||||
confirmPwd: [{ required: true, message: this.$t('config.user.reinputPwd'), trigger: 'blur' }, { validator: validateConfirmPass, trigger: 'blur' }]
|
confirmPin: [{ required: true, message: this.$t('config.user.reinputPin'), trigger: 'blur' }, { validator: validateConfirmPass, trigger: 'blur' }]
|
||||||
},
|
},
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
@@ -77,8 +77,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
dialogOpened: function () {
|
dialogOpened: function () {
|
||||||
if (this.$refs.changePwdForm) {
|
if (this.$refs.changePinForm) {
|
||||||
this.$refs.changePwdForm.resetFields()
|
this.$refs.changePinForm.resetFields()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dialogClosed: function () {
|
dialogClosed: function () {
|
||||||
@@ -87,12 +87,12 @@ export default {
|
|||||||
close: function () {
|
close: function () {
|
||||||
this.visible = false
|
this.visible = false
|
||||||
},
|
},
|
||||||
changePwd: function () {
|
changePin: function () {
|
||||||
this.$refs.changePwdForm.validate((valid) => {
|
this.$refs.changePinForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const paramObj = {
|
const paramObj = {
|
||||||
pin: this.user.pwd,
|
pin: this.user.pin,
|
||||||
newPin: this.user.newPwd
|
newPin: this.user.newPin
|
||||||
}
|
}
|
||||||
this.$get('/sys/user/pin?oldPin=' + paramObj.pin + '&newPin=' + paramObj.newPin).then(response => {
|
this.$get('/sys/user/pin?oldPin=' + paramObj.pin + '&newPin=' + paramObj.newPin).then(response => {
|
||||||
if (response && response.code == 200) {
|
if (response && response.code == 200) {
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
<div class="mib-browser-ad-search-label">{{$t('login.pin')}}</div>
|
<div class="mib-browser-ad-search-label">{{$t('login.pin')}}</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="17">
|
<el-col :span="17">
|
||||||
<el-input type="password" class="input-x-mini-24" v-model.trim="searchParamPop.auth.password" id="mib-browser-password"></el-input>
|
<el-input type="password" class="input-x-mini-24" v-model.trim="searchParamPop.auth.pin" id="mib-browser-pin"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -118,10 +118,10 @@
|
|||||||
|
|
||||||
<el-row class="mib-browser-ad-search-item" v-if="searchParamPop.auth.securityLevel == 'authPriv'">
|
<el-row class="mib-browser-ad-search-item" v-if="searchParamPop.auth.securityLevel == 'authPriv'">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<div class="mib-browser-ad-search-label">{{$t('project.module.privpin')}}</div>
|
<div class="mib-browser-ad-search-label">{{$t('project.module.privPin')}}</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="17">
|
<el-col :span="17">
|
||||||
<el-input type="password" class="input-x-mini-24" v-model.trim="searchParamPop.auth.privPassword" id="mib-browser-privPassword"></el-input>
|
<el-input type="password" class="input-x-mini-24" v-model.trim="searchParamPop.auth.privPin" id="mib-browser-privPassword"></el-input>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
@@ -285,11 +285,11 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
auth: {
|
auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
pin: '',
|
||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
},
|
},
|
||||||
type: '',
|
type: '',
|
||||||
value: ''
|
value: ''
|
||||||
@@ -303,11 +303,11 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
auth: {
|
auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
pin: '',
|
||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
operationData: ['get', 'walk', 'getnext', 'set'],
|
operationData: ['get', 'walk', 'getnext', 'set'],
|
||||||
@@ -453,11 +453,11 @@ export default {
|
|||||||
community: 'public',
|
community: 'public',
|
||||||
auth: {
|
auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
pin: '',
|
||||||
securityLevel: '',
|
securityLevel: '',
|
||||||
authProtocol: '',
|
authProtocol: '',
|
||||||
privProtocol: '',
|
privProtocol: '',
|
||||||
privPassword: ''
|
privPin: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -481,10 +481,10 @@ export default {
|
|||||||
if (this.searchParamPop.version == 3) {
|
if (this.searchParamPop.version == 3) {
|
||||||
this.searchParamPop.auth.username = snmpAccount.params.username
|
this.searchParamPop.auth.username = snmpAccount.params.username
|
||||||
this.searchParamPop.auth.securityLevel = snmpAccount.params.securityLevel
|
this.searchParamPop.auth.securityLevel = snmpAccount.params.securityLevel
|
||||||
this.searchParamPop.auth.password = snmpAccount.params.password
|
this.searchParamPop.auth.pin = snmpAccount.params.pin
|
||||||
this.searchParamPop.auth.authProtocol = snmpAccount.params.authProtocol
|
this.searchParamPop.auth.authProtocol = snmpAccount.params.authProtocol
|
||||||
if (this.searchParamPop.auth.securityLevel == 'authPriv') { this.searchParamPop.auth.privProtocol = snmpAccount.params.privProtocol }
|
if (this.searchParamPop.auth.securityLevel == 'authPriv') { this.searchParamPop.auth.privProtocol = snmpAccount.params.privProtocol }
|
||||||
this.searchParamPop.auth.privPassword = snmpAccount.params.privPassword
|
this.searchParamPop.auth.privPin = snmpAccount.params.privPin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -312,9 +312,9 @@ export default {
|
|||||||
this.activeStep = 2
|
this.activeStep = 2
|
||||||
this.step = 2
|
this.step = 2
|
||||||
if (response.code == 574004) { // 密码无效
|
if (response.code == 574004) { // 密码无效
|
||||||
this.$alert(this.$t('setup.invalidpin'), { type: 'warning' })
|
this.$alert(this.$t('setup.invalidPin'), { type: 'warning' })
|
||||||
} else if (response.code == 574005) {
|
} else if (response.code == 574005) {
|
||||||
this.$alert(this.$t('setup.requirepin'), { type: 'warning' })
|
this.$alert(this.$t('setup.requirePin'), { type: 'warning' })
|
||||||
} else if (response.code == 574002) {
|
} else if (response.code == 574002) {
|
||||||
this.$alert(this.$t('setup.invalidCode', { page: this.$t('setup.welcomePage') }), { type: 'warning' })
|
this.$alert(this.$t('setup.invalidCode', { page: this.$t('setup.welcomePage') }), { type: 'warning' })
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -106,9 +106,9 @@
|
|||||||
<el-form-item :label="$t('config.system.email.smtpAccount')" prop="email_auth_account">
|
<el-form-item :label="$t('config.system.email.smtpAccount')" prop="email_auth_account">
|
||||||
<el-input v-model="email.email_auth_account" :disabled="email.email_enable == 'off'" id="system-email-email_smtp_account"> autocomplete="off"</el-input>
|
<el-input v-model="email.email_auth_account" :disabled="email.email_enable == 'off'" id="system-email-email_smtp_account"> autocomplete="off"</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.system.email.smtpPwd')" class="has-tip" prop="email_auth_password">
|
<el-form-item :label="$t('config.system.email.smtpPin')" class="has-tip" prop="email_auth_pin">
|
||||||
<el-input v-model="email.email_auth_password" type="password" :show-password="false" :disabled="email.email_enable == 'off'" autocomplete="off" id="system-email-email_smtp_password"></el-input>
|
<el-input v-model="email.email_auth_pin" type="password" :show-password="false" :disabled="email.email_enable == 'off'" autocomplete="off" id="system-email-email_smtp_password"></el-input>
|
||||||
<div class="el-form-item__tip">{{$t("config.system.email.pwdTip")}}</div>
|
<div class="el-form-item__tip">{{$t("config.system.email.pinTip")}}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.system.email.sendAccount')" class="has-tip" prop="email_send_account">
|
<el-form-item :label="$t('config.system.email.sendAccount')" class="has-tip" prop="email_send_account">
|
||||||
<el-input v-model="email.email_send_account" :disabled="email.email_enable == 'off'" id="system-email-email_send_account"></el-input>
|
<el-input v-model="email.email_send_account" :disabled="email.email_enable == 'off'" id="system-email-email_send_account"></el-input>
|
||||||
@@ -170,8 +170,8 @@
|
|||||||
<el-form-item :label="$t('config.system.ldap.dn')" prop="ldap_dn">
|
<el-form-item :label="$t('config.system.ldap.dn')" prop="ldap_dn">
|
||||||
<el-input v-model="ldap.ldap_dn" id="system-ldap-ldap_dn"></el-input>
|
<el-input v-model="ldap.ldap_dn" id="system-ldap-ldap_dn"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.system.ldap.pwd')" prop="ldap_password">
|
<el-form-item :label="$t('config.system.ldap.pin')" prop="ldap_pin">
|
||||||
<el-input v-model="ldap.ldap_password" type="password" id="system-ldap-ldap_password"></el-input>
|
<el-input v-model="ldap.ldap_pin" type="password" id="system-ldap-ldap_pin"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.system.ldap.ou')" class="has-tip" prop="ldap_ou">
|
<el-form-item :label="$t('config.system.ldap.ou')" class="has-tip" prop="ldap_ou">
|
||||||
<el-input v-model="ldap.ldap_ou" id="system-ldap-ldap_ou"></el-input>
|
<el-input v-model="ldap.ldap_ou" id="system-ldap-ldap_ou"></el-input>
|
||||||
@@ -229,8 +229,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('config.system.reset.pwd')" prop="password">
|
<el-form-item :label="$t('config.system.reset.pin')" prop="pin">
|
||||||
<el-input id="system-reset-password" v-model="reset.password" type="password"></el-input>
|
<el-input id="system-reset-pin" v-model="reset.pin" type="password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<button @click="resetSys()" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" type="button" v-has="'system_reset_reset'" :disabled="prevent_opt.save" :class="{'nz-btn-disabled':prevent_opt.save}">{{$t('overall.reset')}}</button>
|
<button @click="resetSys()" class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" type="button" v-has="'system_reset_reset'" :disabled="prevent_opt.save" :class="{'nz-btn-disabled':prevent_opt.save}">{{$t('overall.reset')}}</button>
|
||||||
@@ -259,7 +259,7 @@ export default {
|
|||||||
basic: {
|
basic: {
|
||||||
alert_api: '',
|
alert_api: '',
|
||||||
asset_ping_interval: '300', // 检查周期,单位:s
|
asset_ping_interval: '300', // 检查周期,单位:s
|
||||||
session_timeout:'30',
|
session_timeout: '30',
|
||||||
storage_local_retention: 15 * 24,
|
storage_local_retention: 15 * 24,
|
||||||
system_name: '',
|
system_name: '',
|
||||||
system_logo: '',
|
system_logo: '',
|
||||||
@@ -294,7 +294,7 @@ export default {
|
|||||||
email_port: 25,
|
email_port: 25,
|
||||||
email_timeout: 10,
|
email_timeout: 10,
|
||||||
email_auth_account: '',
|
email_auth_account: '',
|
||||||
email_auth_password: '',
|
email_auth_pin: '',
|
||||||
email_send_account: '',
|
email_send_account: '',
|
||||||
email_test_account: '',
|
email_test_account: '',
|
||||||
email_security_type: 'NONE'
|
email_security_type: 'NONE'
|
||||||
@@ -330,7 +330,7 @@ export default {
|
|||||||
ldap: {
|
ldap: {
|
||||||
ldap_address: '',
|
ldap_address: '',
|
||||||
ldap_dn: '',
|
ldap_dn: '',
|
||||||
ldap_password: '',
|
ldap_pin: '',
|
||||||
ldap_ou: '',
|
ldap_ou: '',
|
||||||
ldap_user_filter: '',
|
ldap_user_filter: '',
|
||||||
ldap_mapping: '',
|
ldap_mapping: '',
|
||||||
@@ -346,7 +346,7 @@ export default {
|
|||||||
},
|
},
|
||||||
reset: {
|
reset: {
|
||||||
type: [],
|
type: [],
|
||||||
password: ''
|
pin: ''
|
||||||
},
|
},
|
||||||
linkTemp: {
|
linkTemp: {
|
||||||
name: '', url: ''
|
name: '', url: ''
|
||||||
@@ -376,7 +376,7 @@ export default {
|
|||||||
},
|
},
|
||||||
resetRules: {
|
resetRules: {
|
||||||
type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
||||||
password: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
|
pin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
|
||||||
},
|
},
|
||||||
resetOptions: [
|
resetOptions: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ export default {
|
|||||||
this.$get('/module/stat', { id: item.id }).then(res => {
|
this.$get('/module/stat', { id: item.id }).then(res => {
|
||||||
item.state = res.data
|
item.state = res.data
|
||||||
})
|
})
|
||||||
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.iconId}`))
|
promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.iconId}/1`))
|
||||||
})
|
})
|
||||||
Promise.all(promiseArr).then(res => {
|
Promise.all(promiseArr).then(res => {
|
||||||
arr.forEach((item, index) => {
|
arr.forEach((item, index) => {
|
||||||
|
|||||||
@@ -22,48 +22,6 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</template>
|
</template>
|
||||||
</select-panel>
|
</select-panel>
|
||||||
<!--<el-dropdown @command="panelChange" class="panel-dropdown-title" trigger="click" placement="bottom-start" >
|
|
||||||
<el-row :gutter="10" class="el-dropdown-link" style="padding-right: 5px">
|
|
||||||
<el-col :span="21" class="panel-list-title" :title="showPanel.name">{{showPanel.name}}</el-col>
|
|
||||||
<el-col :span="3" style="padding-left:0px !important;"><i class="nz-icon nz-icon-arrow-down"></i></el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-dropdown-menu class="nz-dashboard-dropdown panel-dropdown-title-space" slot="dropdown" >
|
|
||||||
<!–<el-dropdown-item>{{$t('dashboard.panel.createPanelTitleSec')}}</el-dropdown-item>–>
|
|
||||||
<div ref="dashboardScrollbar" style="height: 100%; overflow: auto">
|
|
||||||
<el-dropdown-item >
|
|
||||||
<el-row class="panel-list-width" :gutter="10" >
|
|
||||||
<el-col :span="21"><el-input :placeholder="$t('overall.search')" @click.native.stop="filterPanelFocus($event)" @input="filterPanelFunc" clearable size="mini" v-model="filterPanel"></el-input></el-col>
|
|
||||||
<el-col :span="3"><span :title='$t("dashboard.panel.createPanelTitleSec")' @click="toAdd" v-has="'panel_toAdd'"><i class="nz-icon nz-icon-plus"></i></span></el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-dropdown-item>
|
|
||||||
<draggable v-model="panelData" @start="start" @end="end" :move="move" :key
|
|
||||||
:scroll-sensitivity="150"
|
|
||||||
:options="{
|
|
||||||
group:{name:'chartGroup',pull:'false'},
|
|
||||||
dragClass:'drag-chart-class',
|
|
||||||
fallbackClass:'fallback-class',
|
|
||||||
forceFallback:true,
|
|
||||||
ghostClass:'chart-ghost',
|
|
||||||
chosenClass:'choose-class',
|
|
||||||
scroll:true,
|
|
||||||
scrollFn:function(offsetX,offsetY,originalEvent,touchEvt,hoverTargetEI){},
|
|
||||||
animation:150,
|
|
||||||
handle:'.panelContent',
|
|
||||||
}" >
|
|
||||||
<el-dropdown-item v-for="item in showPanelList" :key="item.id+1" class="panel-title-li"
|
|
||||||
:class="showPanel.id==item.id?'nz-dashboard-dropdown-bg':''" :command="item">
|
|
||||||
<el-row :gutter="10" class="panel-list-width" >
|
|
||||||
<el-col :span="2" class="panelContent move-area"><i class="nz-icon nz-icon-sort4"></i></el-col>
|
|
||||||
<el-col :span="17" class="panel-list-item" :title="item.name">{{item.name}}</el-col>
|
|
||||||
<el-col :span="1"><span @click.stop="del(item)" class="panel-dropdown-btn panel-dropdown-btn-delete" v-has="'panel_delete'"><i class="nz-icon nz-icon-delete"></i></span></el-col>
|
|
||||||
<el-col :span="1"> </el-col>
|
|
||||||
<el-col :span="1"><span @click.stop="edit(item)" class="panel-dropdown-btn" v-has="'panel_toEdit'"><i class="nz-icon nz-icon-edit"></i></span></el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-dropdown-item>
|
|
||||||
</draggable>
|
|
||||||
</div>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>-->
|
|
||||||
</div>
|
</div>
|
||||||
<div class="top-tool-right">
|
<div class="top-tool-right">
|
||||||
<div class="top-tool-search margin-r-20">
|
<div class="top-tool-search margin-r-20">
|
||||||
@@ -73,7 +31,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<pick-time id="panel" ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false"></pick-time>
|
<pick-time id="panel" ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false"></pick-time>
|
||||||
<export-excel
|
|
||||||
|
<button id="panel-add-chart" v-has="'panel_chart_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10"
|
||||||
|
type="button" @click="addChart">
|
||||||
|
<i class="nz-icon-create-square nz-icon"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<top-tool-more-options
|
||||||
id="panel"
|
id="panel"
|
||||||
:params="filter"
|
:params="filter"
|
||||||
:permissions="{
|
:permissions="{
|
||||||
@@ -86,15 +50,17 @@
|
|||||||
import-url="/visual/panel/import"
|
import-url="/visual/panel/import"
|
||||||
@afterImport="dateChange"
|
@afterImport="dateChange"
|
||||||
>
|
>
|
||||||
<template slot="optionZone">
|
<template v-slot:before>
|
||||||
<button id="panel-add-chart" v-has="'panel_chart_add'" :title="$t('overall.createChart')"
|
<el-dropdown-item>
|
||||||
class="top-tool-btn" @click="addChart">
|
<div id="panel-lock" @click="panelLock=!panelLock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i>{{panelLock ? 'Locked' : 'Unlocked'}}</div>
|
||||||
<i class="nz-icon-create-square nz-icon"></i>
|
</el-dropdown-item>
|
||||||
</button>
|
|
||||||
</template>
|
</template>
|
||||||
</export-excel>
|
<template v-slot:after>
|
||||||
<button id="chart-temp-add" class="top-tool-btn margin-l-10" type="button" @click="addChartByTemp"><i class='nz-icon nz-icon-lock'></i></button>
|
<el-dropdown-item v-has="'panel_chart_add'">
|
||||||
<button id="panel-lock" class="top-tool-btn margin-l-10" type="button" @click="panelLock=!panelLock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i></button>
|
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-download1"></i>Add template</div>
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</top-tool-more-options>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,11 +93,11 @@ import ChartBox from './chartBox'
|
|||||||
import ChartList from '../../charts/chart-list'
|
import ChartList from '../../charts/chart-list'
|
||||||
import bus from '../../../libs/bus'
|
import bus from '../../../libs/bus'
|
||||||
import pickTime from '../../common/pickTime'
|
import pickTime from '../../common/pickTime'
|
||||||
import exportXLSX from '../../common/exportXLSX'
|
|
||||||
import selectPanel from '../../common/popBox/selectPanel'
|
import selectPanel from '../../common/popBox/selectPanel'
|
||||||
import panelBox from '@/components/common/rightBox/panelBox'
|
import panelBox from '@/components/common/rightBox/panelBox'
|
||||||
import chartTempBox from '@/components/common/rightBox/chartTempBox'
|
import chartTempBox from '@/components/common/rightBox/chartTempBox'
|
||||||
|
import topToolMoreOptions from '@/components/common/popBox/topToolMoreOptions'
|
||||||
|
import Template from '@/components/page/config/template'
|
||||||
export default {
|
export default {
|
||||||
name: 'panel',
|
name: 'panel',
|
||||||
data () {
|
data () {
|
||||||
@@ -216,12 +182,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
Template,
|
||||||
'chart-box': ChartBox,
|
'chart-box': ChartBox,
|
||||||
'chart-list': ChartList,
|
'chart-list': ChartList,
|
||||||
'pick-time': pickTime,
|
'pick-time': pickTime,
|
||||||
'export-excel': exportXLSX,
|
|
||||||
selectPanel,
|
|
||||||
'panel-box': panelBox,
|
'panel-box': panelBox,
|
||||||
|
topToolMoreOptions,
|
||||||
|
selectPanel,
|
||||||
chartTempBox
|
chartTempBox
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -309,7 +276,7 @@ export default {
|
|||||||
this.rightBox.chart.show = true
|
this.rightBox.chart.show = true
|
||||||
},
|
},
|
||||||
addChartByTemp () {
|
addChartByTemp () {
|
||||||
this.chart = Object.assign({},this.blankChartTemp)
|
this.chart = Object.assign({}, this.blankChartTemp)
|
||||||
this.chart.panelId = this.showPanel.id
|
this.chart.panelId = this.showPanel.id
|
||||||
this.rightBox.chartTemp.show = true
|
this.rightBox.chartTemp.show = true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export default {
|
|||||||
type: 'query',
|
type: 'query',
|
||||||
label: 'query',
|
label: 'query',
|
||||||
disabled: false
|
disabled: false
|
||||||
},{
|
}, {
|
||||||
id: 34,
|
id: 34,
|
||||||
name: this.$t('project.project.project'),
|
name: this.$t('project.project.project'),
|
||||||
// name: this.$t('asset.asset'),
|
// name: this.$t('asset.asset'),
|
||||||
@@ -278,6 +278,9 @@ export default {
|
|||||||
},
|
},
|
||||||
reloadTable (obj) {
|
reloadTable (obj) {
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach(key => {
|
||||||
|
if (key === 'change') {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.searchCheckBox[key] = obj[key].join(',')
|
this.searchCheckBox[key] = obj[key].join(',')
|
||||||
})
|
})
|
||||||
console.log(obj, this.searchCheckBox)
|
console.log(obj, this.searchCheckBox)
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export default {
|
|||||||
labels: '',
|
labels: '',
|
||||||
basic_auth: {
|
basic_auth: {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
pin: ''
|
||||||
},
|
},
|
||||||
bearer_token: ''
|
bearer_token: ''
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ import topologyL5 from '@/components/common/project/topologyL5'
|
|||||||
export default {
|
export default {
|
||||||
name: 'project2',
|
name: 'project2',
|
||||||
components: {
|
components: {
|
||||||
topologyL5,
|
topologyL5
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import moment from 'moment-timezone'
|
||||||
Date.prototype.setStart = function () {
|
Date.prototype.setStart = function () {
|
||||||
this.setHours(0)
|
this.setHours(0)
|
||||||
this.setMinutes(0)
|
this.setMinutes(0)
|
||||||
@@ -261,6 +261,7 @@ export default new Vue({
|
|||||||
// 将本地时区转为系统配置的时区
|
// 将本地时区转为系统配置的时区
|
||||||
computeTimezone: function (sourceTime) {
|
computeTimezone: function (sourceTime) {
|
||||||
let offset = localStorage.getItem('nz-sys-timezone')
|
let offset = localStorage.getItem('nz-sys-timezone')
|
||||||
|
offset = moment.tz(offset).zoneAbbr()
|
||||||
if (offset && offset !== 'undefined') {
|
if (offset && offset !== 'undefined') {
|
||||||
offset = Number.parseInt(offset)
|
offset = Number.parseInt(offset)
|
||||||
const date = new Date(sourceTime)
|
const date = new Date(sourceTime)
|
||||||
@@ -296,6 +297,7 @@ export default new Vue({
|
|||||||
},
|
},
|
||||||
UTCTimeToConfigTimezone (utcTime) {
|
UTCTimeToConfigTimezone (utcTime) {
|
||||||
let offset = localStorage.getItem('nz-sys-timezone')
|
let offset = localStorage.getItem('nz-sys-timezone')
|
||||||
|
offset = moment.tz(offset).zoneAbbr()
|
||||||
if (offset && offset !== 'undefined') {
|
if (offset && offset !== 'undefined') {
|
||||||
let time = utcTime
|
let time = utcTime
|
||||||
if (typeof time === 'string' && /(\d+?-){2}\d+?\s(\d+?:)*\d+/.test(time)) {
|
if (typeof time === 'string' && /(\d+?-){2}\d+?\s(\d+?:)*\d+/.test(time)) {
|
||||||
@@ -310,6 +312,7 @@ export default new Vue({
|
|||||||
},
|
},
|
||||||
configTimezoneToUTCTime: function (configTime) {
|
configTimezoneToUTCTime: function (configTime) {
|
||||||
let offset = localStorage.getItem('nz-sys-timezone')
|
let offset = localStorage.getItem('nz-sys-timezone')
|
||||||
|
offset = moment.tz(offset).zoneAbbr()
|
||||||
if (offset && offset !== 'undefined') {
|
if (offset && offset !== 'undefined') {
|
||||||
let time = configTime
|
let time = configTime
|
||||||
if (typeof time === 'string' && /(\d+?-){2}\d+?\s(\d+?:)*\d+/.test(time)) {
|
if (typeof time === 'string' && /(\d+?-){2}\d+?\s(\d+?:)*\d+/.test(time)) {
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ import pickTime from '@/components/common/pickTime'
|
|||||||
import bus from '@/libs/bus'
|
import bus from '@/libs/bus'
|
||||||
import theme from '@/assets/css/theme.scss'
|
import theme from '@/assets/css/theme.scss'
|
||||||
|
|
||||||
import vSelectPage from 'v-selectpage';
|
import vSelectPage from 'v-selectpage'
|
||||||
Vue.use(vSelectPage);
|
Vue.use(vSelectPage)
|
||||||
|
|
||||||
Vue.component('Pagination', Pagination)
|
Vue.component('Pagination', Pagination)
|
||||||
Vue.component('searchInput', searchInput)
|
Vue.component('searchInput', searchInput)
|
||||||
|
|||||||
Reference in New Issue
Block a user