fix:endpoint 显示bug修改 以及修改 chart 参数

This commit is contained in:
zhangyu
2021-04-27 17:38:58 +08:00
parent 99402bac17
commit 06584204ae
42 changed files with 6164 additions and 1842 deletions

View File

@@ -203,7 +203,7 @@ import textChart from './text-chart'
import chartPie from './chart-pie'
import chartBarStatis from './chart-bar-statistics'
import chartTempData from '@/components/charts/chartTempData'
import {fromRoute} from "@/components/common/js/constants";
import { fromRoute } from '@/components/common/js/constants'
// import visNetwork from './visNetwork'
export default {
name: 'chartList',

View File

@@ -679,7 +679,7 @@ export default {
}
if (!param.query) delete param.query
// 根据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) {
response.data.list.forEach((item, index) => {
item.isLoaded = false

View File

@@ -16,8 +16,8 @@
<div class="sub-list" style='position: relative;'>
<!--el-drawer 打开后会对第一个未隐藏的元素聚焦 所以添加一隐藏的input 防止聚焦-->
<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-submenu index="1" popper-class="fontSizeBox" style="width:40px;">
<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="horizontal" style="width:40px;">
<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">-->
<!--<template slot="title">文字大小</template>-->
@@ -32,7 +32,7 @@
<!--<el-menu-item index="1-2-2">Courier New</el-menu-item>-->
<!--</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>-->
<!-- <el-menu-item @click="showUploadBox" index="2-1">-->
<!-- <div>{{$t('webshell.upload')}}</div>-->
@@ -978,4 +978,10 @@ export default {
div.sp-header{
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>

View File

@@ -50,8 +50,8 @@
import dataListMixin from '@/components/common/mixin/dataList'
import subDataListMixin from '@/components/common/mixin/subDataList'
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
import assetTable from "@/components/common/table/asset/assetTable";
import assetBox from "@/components/common/rightBox/asset/assetBox";
import assetTable from '@/components/common/table/asset/assetTable'
import assetBox from '@/components/common/rightBox/asset/assetBox'
export default {
name: 'assetTab',
mixins: [dataListMixin, subDataListMixin],
@@ -184,7 +184,7 @@ export default {
resolve()
})
})
},
}
},
watch: {
@@ -192,8 +192,8 @@ export default {
immediate: true,
deep: true,
handler (n, o) {
this.searchLabel.dcIds=n.id;
this.getTableData();
this.searchLabel.dcIds = n.id
this.getTableData()
}
}
},
@@ -204,6 +204,6 @@ export default {
this.getDcData()
this.getSnmpCredentialData()
this.getFieldGroupData()
},
}
}
</script>

View File

@@ -41,7 +41,7 @@ import deleteButton from '../../deleteButton'
import dataListMixin from '@/components/common/mixin/dataList'
import subDataListMixin from '@/components/common/mixin/subDataList'
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 {
name: 'cabinetTab',
mixins: [dataListMixin, subDataListMixin],
@@ -89,14 +89,14 @@ export default {
disabled: false
}
]
},
}
}
},
methods: {
// 切换tab
changeTab (tab) {
this.$emit('changeTab', tab)
},
}
},
watch: {
obj: {

View File

@@ -278,7 +278,7 @@ export default {
this.panelDataList = [this.obj]
console.log(this.panelData)
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)
})
}

View File

@@ -182,7 +182,7 @@ const en = {
authPin: 'Password',
authUserTip: 'Username prompt',
authPinTip: 'Password prompt',
authPriKey: 'Key',
authPriKey: 'Key'
},
login: {
username: 'Username',
@@ -600,7 +600,7 @@ const en = {
option: 'Operation', // "操作"
name: 'Name',
dc: 'DataCenter',
type: 'Types',
type: 'Types'
},
config: {
config: 'Settings', // "设置"

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -129,7 +129,7 @@ export default {
type: Object
},
tableTitle: {
type: Array,
type: Array
}
},
data () {

View File

@@ -1562,7 +1562,7 @@ export default {
if (res.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
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)
if (group) {
group.children.push({
@@ -1618,7 +1618,7 @@ export default {
res.data.list.forEach((item, index) => {
item.imageName = 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 })
})
Promise.all(promiseArr).then((res2) => {
@@ -1662,7 +1662,7 @@ export default {
const promiseArr = []
imgidList.forEach((item, index) => {
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 {
promiseArr.push('')
}

View File

@@ -65,6 +65,7 @@
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
@@ -75,19 +76,19 @@
<span>{{scope.row[item.prop].name}}</span>
</template>
<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 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 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 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 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>
<span v-else>{{scope.row[item.prop] ? scope.row[item.prop] : ''}}</span>
</template>
@@ -1130,7 +1131,7 @@ export default {
.add-endpoint{
display: inline-block;
background: #F9F9F9;
border: 1px solid $--primary-border-color;
border: 1px solid #dedede;
border-radius: 2px;
width: 28px;
height: 28px;
@@ -1141,7 +1142,7 @@ export default {
.top-tool-btn{
height: 32px;
width: 32px;
border: 1px solid $--primary-border-color;
border: 1px solid #dedede;
outline: none;
border-radius: 2px;
background-color: #F9F9F9;

View File

@@ -59,7 +59,7 @@ import selectWalk from '../../popBox/selectWalk'
export default {
name: 'modelBox',
components: {
'select-walk': selectWalk,
'select-walk': selectWalk
},
props: {
obj: {
@@ -125,7 +125,7 @@ export default {
this.$refs.modelForm.validate((valid) => {
if (valid) {
if (this.editModel.id) {
console.log(this.editModel);
console.log(this.editModel)
this.$put(this.url, this.editModel).then(res => {
this.prevent_opt.save = false
if (res.code === 200) {
@@ -168,10 +168,9 @@ export default {
} else {
this.saveModel()
}
},
selectWalk (walk) {
console.log(walk);
console.log(walk)
if (this.editModule.walk.indexOf(walk) != -1) {
this.editModule.walk.splice(this.editModule.walk.indexOf(walk), 1)
} else {
@@ -192,7 +191,7 @@ export default {
/* 获取chart列表数据 */
ChartTemplateList () {
this.$get('visual/panel/chart', { pageSize: -1, varType: 1, panelId: 0 }).then(res => {
console.log(res);
console.log(res)
this.chartlList = res.data.list
})
}

View File

@@ -84,7 +84,7 @@ export default {
editDc: {},
rules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
state: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }

View File

@@ -37,7 +37,7 @@
<script>
export default {
name: "cabinetBox",
name: 'cabinetBox',
props: {
obj: { type: Object },
currentDc: { type: Object }

View File

@@ -158,7 +158,7 @@ const searchSelectInfo = { // value: 传给后台的值label显示给用
}, {
value: 4,
label: i18n.t('config.terminallog.statusItem.unknownError')
},
}
]
}
export default searchSelectInfo

View File

@@ -79,7 +79,7 @@
<script>
import table from '@/components/common/mixin/table'
export default {
name: "cabinet Table",
name: 'cabinet Table',
mixins: [table],
data () {
return {
@@ -121,7 +121,7 @@
show: true,
width: 120
}
],
]
}
}
}

View File

@@ -136,7 +136,7 @@ export default {
name: this.$t('dashboard.panel.chartForm.typeVal.group.label')
}
],
]
}
},
methods: {

View File

@@ -162,7 +162,8 @@ export default {
}
},
methods: {
showTableTooltip, hideTableTooltip,
showTableTooltip,
hideTableTooltip,
regNumTest (val) { // 校验是否是数字
return this.regNum.test(val)
},
@@ -186,7 +187,7 @@ export default {
}
}
return ''
},
}
}
}
</script>

View File

@@ -460,7 +460,7 @@ export default {
this.$get('/module/stat', { id: item.id }).then(res => {
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 => {
arr.forEach((item, index) => {

View File

@@ -266,6 +266,7 @@ export default {
response.data.list[i].status = response.data.list[i].status + ''
}
this.tableData = response.data.list
console.log(this.tableData);
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {

View File

@@ -64,7 +64,7 @@ import topologyL5 from '@/components/common/project/topologyL5'
export default {
name: 'project2',
components: {
topologyL5,
topologyL5
},
data () {
return {

View File

@@ -32,8 +32,8 @@ import pickTime from '@/components/common/pickTime'
import bus from '@/libs/bus'
import theme from '@/assets/css/theme.scss'
import vSelectPage from 'v-selectpage';
Vue.use(vSelectPage);
import vSelectPage from 'v-selectpage'
Vue.use(vSelectPage)
Vue.component('Pagination', Pagination)
Vue.component('searchInput', searchInput)