mirror of https://github.com/ElemeFE/element
Merge branch 'dev' into carbon
# Conflicts: # packages/date-picker/src/panel/time.vuepull/7041/head
commit
43ecb8818c
|
@ -1,5 +1,14 @@
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### 1.4.4
|
||||||
|
|
||||||
|
*2017-09-05*
|
||||||
|
|
||||||
|
- Fixed all months disabled in DatePicker month view when `disabledDate` is set, #6768 @qingdengyue
|
||||||
|
- Added `debounce` attribute for Slider, #6820 @langgo
|
||||||
|
- Fixed value of Pagination jumper can be bigger than the total page count, #6842 @huguangju
|
||||||
|
- Fixed TimePicker's focus slipping away when selecting hour to 23 with mouse scroll, #6719 @qingdengyue
|
||||||
|
|
||||||
### 1.4.3
|
### 1.4.3
|
||||||
|
|
||||||
*2017-08-25*
|
*2017-08-25*
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### 1.4.4
|
||||||
|
*2017-09-05*
|
||||||
|
|
||||||
|
- 修复设置了 `disabledDate` 的 DatePicker 在月视图下全部不可选的问题,#6768 @qingdengyue
|
||||||
|
- Slider 新增 `debounce` 属性,#6820 @langgo
|
||||||
|
- 修复 Pagination 的 jumper 中可以输入比最大页数更大的数字的问题,#6842 @huguangju
|
||||||
|
- 修复 TimePicker 的小时数难以通过滚动的方式选中 23 时的问题,#6719 @qingdengyue
|
||||||
|
|
||||||
### 1.4.3
|
### 1.4.3
|
||||||
*2017-08-25*
|
*2017-08-25*
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,7 @@ Selecting a range of values is supported.
|
||||||
| range | whether to select a range | boolean | — | false |
|
| range | whether to select a range | boolean | — | false |
|
||||||
| vertical | vertical mode | boolean | — | false |
|
| vertical | vertical mode | boolean | — | false |
|
||||||
| height | Slider height, required in vertical mode | String | — | — |
|
| height | Slider height, required in vertical mode | String | — | — |
|
||||||
|
|debounce| debounce delay when typing, in millisecond, works when `show-input` is true | number | — | 300 |
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
| Event Name | Description | Parameters |
|
| Event Name | Description | Parameters |
|
||||||
|
|
|
@ -213,3 +213,4 @@ Disabled form elements are not supported in tooltip, see more information at [MD
|
||||||
| manual | whether to control Tooltip manually. `mouseenter` and `mouseleave` won't have effects if set to `true` | boolean | — | false |
|
| manual | whether to control Tooltip manually. `mouseenter` and `mouseleave` won't have effects if set to `true` | boolean | — | false |
|
||||||
| popper-class | custom class name for Tooltip's popper | string | — | — |
|
| popper-class | custom class name for Tooltip's popper | string | — | — |
|
||||||
| enterable | whether the mouse can enter the tooltip | Boolean | — | true |
|
| enterable | whether the mouse can enter the tooltip | Boolean | — | true |
|
||||||
|
| hide-after | timeout in milliseconds to hide tooltip | number | — | 0 |
|
||||||
|
|
|
@ -237,6 +237,7 @@
|
||||||
| range | 是否为范围选择 | boolean | — | false |
|
| range | 是否为范围选择 | boolean | — | false |
|
||||||
| vertical | 是否竖向模式 | boolean | — | false |
|
| vertical | 是否竖向模式 | boolean | — | false |
|
||||||
| height | Slider 高度,竖向模式时必填 | String | — | — |
|
| height | Slider 高度,竖向模式时必填 | String | — | — |
|
||||||
|
| debounce | 输入时的去抖延迟,毫秒,仅在`show-input`等于true时有效 | number | — | 300 |
|
||||||
|
|
||||||
### Events
|
### Events
|
||||||
| 事件名称 | 说明 | 回调参数 |
|
| 事件名称 | 说明 | 回调参数 |
|
||||||
|
|
|
@ -935,7 +935,7 @@
|
||||||
| --------------------- | ---------------------------------------- | --------------------------- | ---- | ----- |
|
| --------------------- | ---------------------------------------- | --------------------------- | ---- | ----- |
|
||||||
| data | 展示数据 | array | — | — |
|
| data | 展示数据 | array | — | — |
|
||||||
| empty-text | 内容为空的时候展示的文本 | String | — | — |
|
| empty-text | 内容为空的时候展示的文本 | String | — | — |
|
||||||
| node-key | 每个树节点用来作为唯一标识的属性,整颗树应该是唯一的 | String | — | — |
|
| node-key | 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的 | String | — | — |
|
||||||
| props | 配置选项,具体看下表 | object | — | — |
|
| props | 配置选项,具体看下表 | object | — | — |
|
||||||
| load | 加载子树数据的方法 | function(node, resolve) | — | — |
|
| load | 加载子树数据的方法 | function(node, resolve) | — | — |
|
||||||
| render-content | 树节点的内容区的渲染 Function | Function(h, { node } | — | — |
|
| render-content | 树节点的内容区的渲染 Function | Function(h, { node } | — | — |
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.3":"1.4"}
|
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.4":"1.4"}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "element-ui",
|
"name": "element-ui",
|
||||||
"version": "1.4.3",
|
"version": "1.4.4",
|
||||||
"description": "A Component Library for Vue.js.",
|
"description": "A Component Library for Vue.js.",
|
||||||
"main": "lib/element-ui.common.js",
|
"main": "lib/element-ui.common.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
|
|
@ -78,18 +78,12 @@
|
||||||
while (date < nextMonth) {
|
while (date < nextMonth) {
|
||||||
if (this.disabledDate(date)) {
|
if (this.disabledDate(date)) {
|
||||||
date = new Date(date.getTime() + 8.64e7);
|
date = new Date(date.getTime() + 8.64e7);
|
||||||
|
flag = true;
|
||||||
} else {
|
} else {
|
||||||
|
flag = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// There is a bug of Chrome.
|
|
||||||
// For example:
|
|
||||||
// var date = new Date('1988-04-01 00:00:00') Fri Apr 01 1988 00:00:00 GMT+0800 (CST)
|
|
||||||
// date.setMonth(4) Sun May 01 1988 00:00:00 GMT+0900 (CDT)
|
|
||||||
// Sometimes the time zone will change.
|
|
||||||
if (date - nextMonth < 8.64e7) {
|
|
||||||
flag = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
style.disabled = flag;
|
style.disabled = flag;
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
visible(val) {
|
visible(val) {
|
||||||
this.currentVisible = val;
|
this.currentVisible = val;
|
||||||
if (val) {
|
if (val) {
|
||||||
|
this.oldHours = this.hours;
|
||||||
|
this.oldMinutes = this.minutes;
|
||||||
|
this.oldSeconds = this.seconds;
|
||||||
this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'));
|
this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -98,6 +101,9 @@
|
||||||
hours: 0,
|
hours: 0,
|
||||||
minutes: 0,
|
minutes: 0,
|
||||||
seconds: 0,
|
seconds: 0,
|
||||||
|
oldHours: 0,
|
||||||
|
oldMinutes: 0,
|
||||||
|
oldSeconds: 0,
|
||||||
selectableRange: [],
|
selectableRange: [],
|
||||||
currentDate: this.$options.defaultValue || this.date || new Date(),
|
currentDate: this.$options.defaultValue || this.date || new Date(),
|
||||||
currentVisible: this.visible || false,
|
currentVisible: this.visible || false,
|
||||||
|
@ -119,7 +125,14 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.$emit('pick');
|
this.currentDate.setHours(this.oldHours);
|
||||||
|
this.currentDate.setMinutes(this.oldMinutes);
|
||||||
|
this.currentDate.setSeconds(this.oldSeconds);
|
||||||
|
this.hours = this.currentDate.getHours();
|
||||||
|
this.minutes = this.currentDate.getMinutes();
|
||||||
|
this.seconds = this.currentDate.getSeconds();
|
||||||
|
const date = new Date(limitRange(this.currentDate, this.selectableRange, 'HH:mm:ss'));
|
||||||
|
this.$emit('pick', date);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChange(date) {
|
handleChange(date) {
|
||||||
|
|
|
@ -45,7 +45,8 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
timeout: null,
|
timeout: null,
|
||||||
visible: false
|
visible: false,
|
||||||
|
triggerElm: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -63,37 +64,39 @@
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
show() {
|
show() {
|
||||||
|
if (this.triggerElm.disabled) return;
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
}, 250);
|
}, 250);
|
||||||
},
|
},
|
||||||
hide() {
|
hide() {
|
||||||
|
if (this.triggerElm.disabled) return;
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
}, 150);
|
}, 150);
|
||||||
},
|
},
|
||||||
handleClick() {
|
handleClick() {
|
||||||
|
if (this.triggerElm.disabled) return;
|
||||||
this.visible = !this.visible;
|
this.visible = !this.visible;
|
||||||
},
|
},
|
||||||
initEvent() {
|
initEvent() {
|
||||||
let { trigger, show, hide, handleClick, splitButton } = this;
|
let { trigger, show, hide, handleClick, splitButton } = this;
|
||||||
let triggerElm = splitButton
|
this.triggerElm = splitButton
|
||||||
? this.$refs.trigger.$el
|
? this.$refs.trigger.$el
|
||||||
: this.$slots.default[0].elm;
|
: this.$slots.default[0].elm;
|
||||||
|
|
||||||
if (triggerElm.disabled) return;
|
|
||||||
if (trigger === 'hover') {
|
if (trigger === 'hover') {
|
||||||
triggerElm.addEventListener('mouseenter', show);
|
this.triggerElm.addEventListener('mouseenter', show);
|
||||||
triggerElm.addEventListener('mouseleave', hide);
|
this.triggerElm.addEventListener('mouseleave', hide);
|
||||||
|
|
||||||
let dropdownElm = this.$slots.dropdown[0].elm;
|
let dropdownElm = this.$slots.dropdown[0].elm;
|
||||||
|
|
||||||
dropdownElm.addEventListener('mouseenter', show);
|
dropdownElm.addEventListener('mouseenter', show);
|
||||||
dropdownElm.addEventListener('mouseleave', hide);
|
dropdownElm.addEventListener('mouseleave', hide);
|
||||||
} else if (trigger === 'click') {
|
} else if (trigger === 'click') {
|
||||||
triggerElm.addEventListener('click', handleClick);
|
this.triggerElm.addEventListener('click', handleClick);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleMenuItemClick(command, instance) {
|
handleMenuItemClick(command, instance) {
|
||||||
|
|
|
@ -19,6 +19,10 @@ LoadingConstructor.prototype.originalPosition = '';
|
||||||
LoadingConstructor.prototype.originalOverflow = '';
|
LoadingConstructor.prototype.originalOverflow = '';
|
||||||
|
|
||||||
LoadingConstructor.prototype.close = function() {
|
LoadingConstructor.prototype.close = function() {
|
||||||
|
if (this.fullscreen) {
|
||||||
|
fullscreenLoading = undefined;
|
||||||
|
}
|
||||||
|
this.$on('after-leave', _ => {
|
||||||
if (this.fullscreen && this.originalOverflow !== 'hidden') {
|
if (this.fullscreen && this.originalOverflow !== 'hidden') {
|
||||||
document.body.style.overflow = this.originalOverflow;
|
document.body.style.overflow = this.originalOverflow;
|
||||||
}
|
}
|
||||||
|
@ -27,13 +31,9 @@ LoadingConstructor.prototype.close = function() {
|
||||||
} else {
|
} else {
|
||||||
this.target.style.position = this.originalPosition;
|
this.target.style.position = this.originalPosition;
|
||||||
}
|
}
|
||||||
if (this.fullscreen) {
|
if (this.$el && this.$el.parentNode) {
|
||||||
fullscreenLoading = undefined;
|
|
||||||
}
|
|
||||||
this.$on('after-leave', _ => {
|
|
||||||
this.$el &&
|
|
||||||
this.$el.parentNode &&
|
|
||||||
this.$el.parentNode.removeChild(this.$el);
|
this.$el.parentNode.removeChild(this.$el);
|
||||||
|
}
|
||||||
this.$destroy();
|
this.$destroy();
|
||||||
});
|
});
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
|
|
@ -192,16 +192,25 @@ export default {
|
||||||
handleFocus(event) {
|
handleFocus(event) {
|
||||||
this.oldValue = event.target.value;
|
this.oldValue = event.target.value;
|
||||||
},
|
},
|
||||||
|
handleBlur({ target }) {
|
||||||
|
this.reassignMaxValue(target);
|
||||||
|
},
|
||||||
handleKeyUp(event) {
|
handleKeyUp(event) {
|
||||||
const key = event.key || '';
|
const key = event.key || '';
|
||||||
const keyCode = event.keyCode || '';
|
const keyCode = event.keyCode || '';
|
||||||
if ((key && key === 'Enter') || (keyCode && keyCode === 13)) {
|
if ((key && key === 'Enter') || (keyCode && keyCode === 13)) {
|
||||||
|
this.reassignMaxValue(event.target);
|
||||||
this.handleChange({ target: event.target });
|
this.handleChange({ target: event.target });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleChange({ target }) {
|
handleChange({ target }) {
|
||||||
this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(target.value);
|
this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(target.value);
|
||||||
this.oldValue = null;
|
this.oldValue = null;
|
||||||
|
},
|
||||||
|
reassignMaxValue(target) {
|
||||||
|
if (+target.value > this.$parent.internalPageCount) {
|
||||||
|
target.value = this.$parent.internalPageCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -213,11 +222,12 @@ export default {
|
||||||
class="el-pagination__editor"
|
class="el-pagination__editor"
|
||||||
type="number"
|
type="number"
|
||||||
min={ 1 }
|
min={ 1 }
|
||||||
max={ this.internalPageCount }
|
max={ this.$parent.internalPageCount }
|
||||||
value={ this.$parent.internalCurrentPage }
|
value={ this.$parent.internalCurrentPage }
|
||||||
domProps-value={ this.$parent.internalCurrentPage }
|
domProps-value={ this.$parent.internalCurrentPage }
|
||||||
on-change={ this.handleChange }
|
on-change={ this.handleChange }
|
||||||
on-focus={ this.handleFocus }
|
on-focus={ this.handleFocus }
|
||||||
|
on-blur={ this.handleBlur }
|
||||||
on-keyup={ this.handleKeyUp }
|
on-keyup={ this.handleKeyUp }
|
||||||
number/>
|
number/>
|
||||||
{ this.t('el.pagination.pageClassifier') }
|
{ this.t('el.pagination.pageClassifier') }
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
classMap: {},
|
classMap: {},
|
||||||
colorMap: {},
|
|
||||||
pointerAtLeftHalf: true,
|
pointerAtLeftHalf: true,
|
||||||
currentValue: this.value,
|
currentValue: this.value,
|
||||||
hoverIndex: -1
|
hoverIndex: -1
|
||||||
|
@ -159,6 +158,16 @@
|
||||||
return this.getValueFromMap(this.currentValue, this.classMap);
|
return this.getValueFromMap(this.currentValue, this.classMap);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
colorMap() {
|
||||||
|
return {
|
||||||
|
lowColor: this.colors[0],
|
||||||
|
mediumColor: this.colors[1],
|
||||||
|
highColor: this.colors[2],
|
||||||
|
voidColor: this.voidColor,
|
||||||
|
disabledVoidColor: this.disabledVoidColor
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
activeColor() {
|
activeColor() {
|
||||||
return this.getValueFromMap(this.currentValue, this.colorMap);
|
return this.getValueFromMap(this.currentValue, this.colorMap);
|
||||||
},
|
},
|
||||||
|
@ -274,13 +283,6 @@
|
||||||
voidClass: this.voidIconClass,
|
voidClass: this.voidIconClass,
|
||||||
disabledVoidClass: this.disabledVoidIconClass
|
disabledVoidClass: this.disabledVoidIconClass
|
||||||
};
|
};
|
||||||
this.colorMap = {
|
|
||||||
lowColor: this.colors[0],
|
|
||||||
mediumColor: this.colors[1],
|
|
||||||
highColor: this.colors[2],
|
|
||||||
voidColor: this.voidColor,
|
|
||||||
disabledVoidColor: this.disabledVoidColor
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -660,8 +660,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
getValueKey(item) {
|
getValueKey(item) {
|
||||||
const type = typeof item.value;
|
if (Object.prototype.toString.call(item.value).toLowerCase() !== '[object object]') {
|
||||||
if (type === 'number' || type === 'string') {
|
|
||||||
return item.value;
|
return item.value;
|
||||||
} else {
|
} else {
|
||||||
return getValueByPath(item.value, this.valueKey);
|
return getValueByPath(item.value, this.valueKey);
|
||||||
|
@ -677,7 +676,6 @@
|
||||||
if (!this.multiple && Array.isArray(this.value)) {
|
if (!this.multiple && Array.isArray(this.value)) {
|
||||||
this.$emit('input', '');
|
this.$emit('input', '');
|
||||||
}
|
}
|
||||||
this.setSelected();
|
|
||||||
|
|
||||||
this.debouncedOnInputChange = debounce(this.debounce, () => {
|
this.debouncedOnInputChange = debounce(this.debounce, () => {
|
||||||
this.onInputChange();
|
this.onInputChange();
|
||||||
|
@ -700,6 +698,7 @@
|
||||||
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
|
this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.setSelected();
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
:controls="showInputControls"
|
:controls="showInputControls"
|
||||||
:min="min"
|
:min="min"
|
||||||
:max="max"
|
:max="max"
|
||||||
|
:debounce="debounce"
|
||||||
size="small">
|
size="small">
|
||||||
</el-input-number>
|
</el-input-number>
|
||||||
<div class="el-slider__runway"
|
<div class="el-slider__runway"
|
||||||
|
@ -102,6 +103,10 @@
|
||||||
},
|
},
|
||||||
height: {
|
height: {
|
||||||
type: String
|
type: String
|
||||||
|
},
|
||||||
|
debounce: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default {
|
||||||
on-mouseout={ this.handleMouseOut }
|
on-mouseout={ this.handleMouseOut }
|
||||||
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
||||||
on-click={ ($event) => this.handleHeaderClick($event, column) }
|
on-click={ ($event) => this.handleHeaderClick($event, column) }
|
||||||
class={ [column.id, column.order, column.headerAlign, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex, columns) ? 'is-hidden' : '', !column.children ? 'is-leaf' : '', column.labelClassName] }>
|
class={ [column.id, column.order, column.headerAlign, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex, columns) ? 'is-hidden' : '', !column.children ? 'is-leaf' : '', column.labelClassName, column.sortable ? 'is-sortable' : ''] }>
|
||||||
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : '', column.labelClassName] }>
|
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : '', column.labelClassName] }>
|
||||||
{
|
{
|
||||||
column.renderHeader
|
column.renderHeader
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "element-theme-default",
|
"name": "element-theme-default",
|
||||||
"version": "1.4.3",
|
"version": "1.4.4",
|
||||||
"description": "Element component default theme.",
|
"description": "Element component default theme.",
|
||||||
"main": "lib/index.css",
|
"main": "lib/index.css",
|
||||||
"style": "lib/index.css",
|
"style": "lib/index.css",
|
||||||
|
|
|
@ -136,6 +136,10 @@
|
||||||
border-bottom: 1px solid var(--table-border-color);
|
border-bottom: 1px solid var(--table-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& th.is-sortable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
@modifier border {
|
@modifier border {
|
||||||
& th, td {
|
& th, td {
|
||||||
border-right: 1px solid var(--table-border-color);
|
border-right: 1px solid var(--table-border-color);
|
||||||
|
|
|
@ -39,9 +39,20 @@ export default {
|
||||||
enterable: {
|
enterable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
hideAfter: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
timeoutPending: null,
|
||||||
|
handlerAdded: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
if (this.$isServer) return;
|
if (this.$isServer) return;
|
||||||
|
|
||||||
|
@ -77,7 +88,7 @@ export default {
|
||||||
if (!this.$slots.default || !this.$slots.default.length) return this.$slots.default;
|
if (!this.$slots.default || !this.$slots.default.length) return this.$slots.default;
|
||||||
|
|
||||||
const vnode = getFirstComponentChild(this.$slots.default);
|
const vnode = getFirstComponentChild(this.$slots.default);
|
||||||
if (!vnode) return vnode;
|
if (!vnode || this.handlerAdded) return vnode;
|
||||||
const data = vnode.data = vnode.data || {};
|
const data = vnode.data = vnode.data || {};
|
||||||
const on = vnode.data.on = vnode.data.on || {};
|
const on = vnode.data.on = vnode.data.on || {};
|
||||||
const nativeOn = vnode.data.nativeOn = vnode.data.nativeOn || {};
|
const nativeOn = vnode.data.nativeOn = vnode.data.nativeOn || {};
|
||||||
|
@ -97,6 +108,7 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
addEventHandle(old, fn) {
|
addEventHandle(old, fn) {
|
||||||
|
this.handlerAdded = true;
|
||||||
return old ? Array.isArray(old) ? old.concat(fn) : [old, fn] : fn;
|
return old ? Array.isArray(old) ? old.concat(fn) : [old, fn] : fn;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -111,15 +123,28 @@ export default {
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
this.showPopper = true;
|
this.showPopper = true;
|
||||||
}, this.openDelay);
|
}, this.openDelay);
|
||||||
|
|
||||||
|
if (this.hideAfter > 0) {
|
||||||
|
this.timeoutPending = setTimeout(() => {
|
||||||
|
this.showPopper = false;
|
||||||
|
}, this.hideAfter);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleClosePopper() {
|
handleClosePopper() {
|
||||||
if (this.enterable && this.expectedState || this.manual) return;
|
if (this.enterable && this.expectedState || this.manual) return;
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
|
|
||||||
|
if (this.timeoutPending) {
|
||||||
|
clearTimeout(this.timeoutPending);
|
||||||
|
}
|
||||||
this.showPopper = false;
|
this.showPopper = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
setExpectedState(expectedState) {
|
setExpectedState(expectedState) {
|
||||||
|
if (expectedState === false) {
|
||||||
|
clearTimeout(this.timeoutPending);
|
||||||
|
}
|
||||||
this.expectedState = expectedState;
|
this.expectedState = expectedState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ export default class Node {
|
||||||
this.expand(null, store.autoExpandParent);
|
this.expand(null, store.autoExpandParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key && store.currentNodeKey && this.key === store.currentNodeKey) {
|
if (key && store.currentNodeKey !== undefined && this.key === store.currentNodeKey) {
|
||||||
store.currentNode = this;
|
store.currentNode = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ if (typeof window !== 'undefined' && window.Vue) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '1.4.3',
|
version: '1.4.4',
|
||||||
locale: locale.use,
|
locale: locale.use,
|
||||||
i18n: locale.i18n,
|
i18n: locale.i18n,
|
||||||
install,
|
install,
|
||||||
|
|
|
@ -2,56 +2,56 @@ export default {
|
||||||
el: {
|
el: {
|
||||||
colorpicker: {
|
colorpicker: {
|
||||||
confirm: 'Confirmar',
|
confirm: 'Confirmar',
|
||||||
clear: 'Limpiar'
|
clear: 'Despejar'
|
||||||
},
|
},
|
||||||
datepicker: {
|
datepicker: {
|
||||||
now: 'Ahora',
|
now: 'Ahora',
|
||||||
today: 'Hoy',
|
today: 'Hoy',
|
||||||
cancel: 'Cancelar',
|
cancel: 'Cancelar',
|
||||||
clear: 'Limpiar',
|
clear: 'Despejar',
|
||||||
confirm: 'Confirmar',
|
confirm: 'Confirmar',
|
||||||
selectDate: 'Seleccionar fecha',
|
selectDate: 'Seleccionar fecha',
|
||||||
selectTime: 'Seleccionar hora',
|
selectTime: 'Seleccionar hora',
|
||||||
startDate: 'Fecha de Inicio',
|
startDate: 'Fecha Incial',
|
||||||
startTime: 'Hora de Inicio',
|
startTime: 'Hora Inicial',
|
||||||
endDate: 'Fecha Final',
|
endDate: 'Fecha Final',
|
||||||
endTime: 'Hora Final',
|
endTime: 'Hora Final',
|
||||||
year: 'Año',
|
year: 'Año',
|
||||||
month1: 'Enero',
|
month1: 'enero',
|
||||||
month2: 'Febrero',
|
month2: 'febrero',
|
||||||
month3: 'Marzo',
|
month3: 'marzo',
|
||||||
month4: 'Abril',
|
month4: 'abril',
|
||||||
month5: 'Mayo',
|
month5: 'mayo',
|
||||||
month6: 'Junio',
|
month6: 'junio',
|
||||||
month7: 'Julio',
|
month7: 'julio',
|
||||||
month8: 'Agosto',
|
month8: 'agosto',
|
||||||
month9: 'Septiembre',
|
month9: 'septiembre',
|
||||||
month10: 'Octubre',
|
month10: 'octubre',
|
||||||
month11: 'Noviembre',
|
month11: 'noviembre',
|
||||||
month12: 'Diciembre',
|
month12: 'diciembre',
|
||||||
// week: 'semana',
|
// week: 'semana',
|
||||||
weeks: {
|
weeks: {
|
||||||
sun: 'Dom',
|
sun: 'dom',
|
||||||
mon: 'Lun',
|
mon: 'lun',
|
||||||
tue: 'Mar',
|
tue: 'mar',
|
||||||
wed: 'Mié',
|
wed: 'mié',
|
||||||
thu: 'Jue',
|
thu: 'jue',
|
||||||
fri: 'Vie',
|
fri: 'vie',
|
||||||
sat: 'Sáb'
|
sat: 'sáb'
|
||||||
},
|
},
|
||||||
months: {
|
months: {
|
||||||
jan: 'Ene',
|
jan: 'ene',
|
||||||
feb: 'Feb',
|
feb: 'feb',
|
||||||
mar: 'Mar',
|
mar: 'mar',
|
||||||
apr: 'Abr',
|
apr: 'abr',
|
||||||
may: 'May',
|
may: 'may',
|
||||||
jun: 'Jun',
|
jun: 'jun',
|
||||||
jul: 'Jul',
|
jul: 'jul',
|
||||||
aug: 'Ago',
|
aug: 'ago',
|
||||||
sep: 'Sep',
|
sep: 'sep',
|
||||||
oct: 'Oct',
|
oct: 'oct',
|
||||||
nov: 'Nov',
|
nov: 'nov',
|
||||||
dec: 'Dic'
|
dec: 'dic'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
|
@ -67,7 +67,7 @@ export default {
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
goto: 'Ir a',
|
goto: 'Ir a',
|
||||||
pagesize: '/pagina',
|
pagesize: '/página',
|
||||||
total: 'Total {total}',
|
total: 'Total {total}',
|
||||||
pageClassifier: ''
|
pageClassifier: ''
|
||||||
},
|
},
|
||||||
|
@ -84,9 +84,9 @@ export default {
|
||||||
table: {
|
table: {
|
||||||
emptyText: 'Sin Datos',
|
emptyText: 'Sin Datos',
|
||||||
confirmFilter: 'Confirmar',
|
confirmFilter: 'Confirmar',
|
||||||
resetFilter: 'Limpiar',
|
resetFilter: 'Reiniciar',
|
||||||
clearFilter: 'Todo',
|
clearFilter: 'Despejar',
|
||||||
sumText: 'Sum' // to be translated
|
sumText: 'Suma'
|
||||||
},
|
},
|
||||||
tree: {
|
tree: {
|
||||||
emptyText: 'Sin Datos'
|
emptyText: 'Sin Datos'
|
||||||
|
@ -94,10 +94,10 @@ export default {
|
||||||
transfer: {
|
transfer: {
|
||||||
noMatch: 'No hay datos que coincidan',
|
noMatch: 'No hay datos que coincidan',
|
||||||
noData: 'Sin datos',
|
noData: 'Sin datos',
|
||||||
titles: ['List 1', 'List 2'], // to be translated
|
titles: ['Lista 1', 'Lista 2'],
|
||||||
filterPlaceholder: 'Enter keyword', // to be translated
|
filterPlaceholder: 'Ingresar palabra clave',
|
||||||
noCheckedFormat: '{total} items', // to be translated
|
noCheckedFormat: '{total} artículos',
|
||||||
hasCheckedFormat: '{checked}/{total} checked' // to be translated
|
hasCheckedFormat: '{checked}/{total} revisados'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
export default {
|
||||||
|
el: {
|
||||||
|
colorpicker: {
|
||||||
|
confirm: 'אישור',
|
||||||
|
clear: 'נקה'
|
||||||
|
},
|
||||||
|
datepicker: {
|
||||||
|
now: 'כעת',
|
||||||
|
today: 'היום',
|
||||||
|
cancel: 'בטל',
|
||||||
|
clear: 'נקה',
|
||||||
|
confirm: 'אישור',
|
||||||
|
selectDate: 'בחר תאריך',
|
||||||
|
selectTime: 'בחר זמן',
|
||||||
|
startDate: 'תאריך התחלה',
|
||||||
|
startTime: 'זמן התחלה',
|
||||||
|
endDate: 'תאריך סיום',
|
||||||
|
endTime: 'זמן סיום',
|
||||||
|
year: '',
|
||||||
|
month1: 'ינואר',
|
||||||
|
month2: 'פברואר',
|
||||||
|
month3: 'מרץ',
|
||||||
|
month4: 'אפריל',
|
||||||
|
month5: 'מאי',
|
||||||
|
month6: 'יוני',
|
||||||
|
month7: 'יולי',
|
||||||
|
month8: 'אוגוסט',
|
||||||
|
month9: 'ספטמבר',
|
||||||
|
month10: 'אוקטובר',
|
||||||
|
month11: 'נובמבר',
|
||||||
|
month12: 'דצמבר',
|
||||||
|
// week: 'week',
|
||||||
|
weeks: {
|
||||||
|
sun: 'א׳',
|
||||||
|
mon: 'ב׳',
|
||||||
|
tue: 'ג׳',
|
||||||
|
wed: 'ד׳',
|
||||||
|
thu: 'ה׳',
|
||||||
|
fri: 'ו׳',
|
||||||
|
sat: 'שבת'
|
||||||
|
},
|
||||||
|
months: {
|
||||||
|
jan: 'ינואר',
|
||||||
|
feb: 'פברואר',
|
||||||
|
mar: 'מרץ',
|
||||||
|
apr: 'אפריל',
|
||||||
|
may: 'מאי',
|
||||||
|
jun: 'יוני',
|
||||||
|
jul: 'יולי',
|
||||||
|
aug: 'אוגוסט',
|
||||||
|
sep: 'ספטמבר',
|
||||||
|
oct: 'אוקטובר',
|
||||||
|
nov: 'נובמבר',
|
||||||
|
dec: 'דצמבר'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
loading: 'טוען',
|
||||||
|
noMatch: 'לא נמצאו נתונים',
|
||||||
|
noData: 'ללא נתונים',
|
||||||
|
placeholder: 'בחר'
|
||||||
|
},
|
||||||
|
cascader: {
|
||||||
|
noMatch: 'ללא נתונים מתאימים',
|
||||||
|
loading: 'טוען',
|
||||||
|
placeholder: 'בחר'
|
||||||
|
},
|
||||||
|
pagination: {
|
||||||
|
goto: 'עבור ל',
|
||||||
|
pagesize: '/page',
|
||||||
|
total: 'כולל {total}',
|
||||||
|
pageClassifier: ''
|
||||||
|
},
|
||||||
|
messagebox: {
|
||||||
|
title: 'הודעה',
|
||||||
|
confirm: 'אישור',
|
||||||
|
cancel: 'בטל',
|
||||||
|
error: 'קלט לא תקין'
|
||||||
|
},
|
||||||
|
upload: {
|
||||||
|
delete: 'מחק',
|
||||||
|
preview: 'תצוגה מקדימה',
|
||||||
|
continue: 'המשך'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
emptyText: 'אין נתונים',
|
||||||
|
confirmFilter: 'אישור',
|
||||||
|
resetFilter: 'נקה',
|
||||||
|
clearFilter: 'הכל',
|
||||||
|
sumText: 'סך'
|
||||||
|
},
|
||||||
|
tree: {
|
||||||
|
emptyText: 'אין נתונים'
|
||||||
|
},
|
||||||
|
transfer: {
|
||||||
|
noMatch: 'אין נתונים מתאימים',
|
||||||
|
noData: 'ללא נתונים',
|
||||||
|
titles: ['רשימה 1', 'רשימה 2'], // to be translated
|
||||||
|
filterPlaceholder: 'הקלד', // to be translated
|
||||||
|
noCheckedFormat: 'פריטים {total}', // to be translated
|
||||||
|
hasCheckedFormat: ' אישור {checked}/{total}' // to be translated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -87,7 +87,7 @@ export default {
|
||||||
confirmFilter: 'Подтвердить',
|
confirmFilter: 'Подтвердить',
|
||||||
resetFilter: 'Сбросить',
|
resetFilter: 'Сбросить',
|
||||||
clearFilter: 'Все',
|
clearFilter: 'Все',
|
||||||
sumText: 'Sum' // to be translated
|
sumText: 'Сумма'
|
||||||
},
|
},
|
||||||
tree: {
|
tree: {
|
||||||
emptyText: 'Нет данных'
|
emptyText: 'Нет данных'
|
||||||
|
@ -95,10 +95,10 @@ export default {
|
||||||
transfer: {
|
transfer: {
|
||||||
noMatch: 'Совпадений не найдено',
|
noMatch: 'Совпадений не найдено',
|
||||||
noData: 'Нет данных',
|
noData: 'Нет данных',
|
||||||
titles: ['List 1', 'List 2'], // to be translated
|
titles: ['Список 1', 'Список 2'],
|
||||||
filterPlaceholder: 'Enter keyword', // to be translated
|
filterPlaceholder: 'Введите ключевое слово',
|
||||||
noCheckedFormat: '{total} items', // to be translated
|
noCheckedFormat: '{total} пунктов',
|
||||||
hasCheckedFormat: '{checked}/{total} checked' // to be translated
|
hasCheckedFormat: '{checked}/{total} выбрано'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default {
|
||||||
select: {
|
select: {
|
||||||
loading: 'Завантаження',
|
loading: 'Завантаження',
|
||||||
noMatch: 'Співпадінь не знайдено',
|
noMatch: 'Співпадінь не знайдено',
|
||||||
noData: 'Нема даних',
|
noData: 'Немає даних',
|
||||||
placeholder: 'Обрати'
|
placeholder: 'Обрати'
|
||||||
},
|
},
|
||||||
cascader: {
|
cascader: {
|
||||||
|
@ -83,22 +83,22 @@ export default {
|
||||||
continue: 'Продовжити'
|
continue: 'Продовжити'
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
emptyText: 'Нема даних',
|
emptyText: 'Немає даних',
|
||||||
confirmFilter: 'Підтвердити',
|
confirmFilter: 'Підтвердити',
|
||||||
resetFilter: 'Скинути',
|
resetFilter: 'Скинути',
|
||||||
clearFilter: 'Все',
|
clearFilter: 'Все',
|
||||||
sumText: 'Sum' // to be translated
|
sumText: 'Сума'
|
||||||
},
|
},
|
||||||
tree: {
|
tree: {
|
||||||
emptyText: 'Нема даних'
|
emptyText: 'Немає даних'
|
||||||
},
|
},
|
||||||
transfer: {
|
transfer: {
|
||||||
noMatch: 'Співпадінь не знайдено',
|
noMatch: 'Співпадінь не знайдено',
|
||||||
noData: 'Обрати',
|
noData: 'Обрати',
|
||||||
titles: ['List 1', 'List 2'], // to be translated
|
titles: ['Список 1', 'Список 2'],
|
||||||
filterPlaceholder: 'Enter keyword', // to be translated
|
filterPlaceholder: 'Введіть ключове слово',
|
||||||
noCheckedFormat: '{total} items', // to be translated
|
noCheckedFormat: '{total} пунктів',
|
||||||
hasCheckedFormat: '{checked}/{total} checked' // to be translated
|
hasCheckedFormat: '{checked}/{total} вибрано'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@ const nodeList = [];
|
||||||
const ctx = '@@clickoutsideContext';
|
const ctx = '@@clickoutsideContext';
|
||||||
|
|
||||||
let startClick;
|
let startClick;
|
||||||
|
let seed = 0;
|
||||||
|
|
||||||
!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
|
!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
|
||||||
|
|
||||||
|
@ -21,7 +22,8 @@ let startClick;
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
bind(el, binding, vnode) {
|
bind(el, binding, vnode) {
|
||||||
const id = nodeList.push(el) - 1;
|
nodeList.push(el);
|
||||||
|
const id = seed++;
|
||||||
const documentHandler = function(mouseup = {}, mousedown = {}) {
|
const documentHandler = function(mouseup = {}, mousedown = {}) {
|
||||||
if (!vnode.context ||
|
if (!vnode.context ||
|
||||||
!mouseup.target ||
|
!mouseup.target ||
|
||||||
|
|
|
@ -184,7 +184,7 @@ describe('Loading', () => {
|
||||||
expect(loadingInstance.visible).to.false;
|
expect(loadingInstance.visible).to.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('target', () => {
|
it('target', done => {
|
||||||
vm = createVue({
|
vm = createVue({
|
||||||
template: `
|
template: `
|
||||||
<div class="loading-container"></div>
|
<div class="loading-container"></div>
|
||||||
|
@ -192,8 +192,14 @@ describe('Loading', () => {
|
||||||
}, true);
|
}, true);
|
||||||
loadingInstance = Loading({ target: '.loading-container' });
|
loadingInstance = Loading({ target: '.loading-container' });
|
||||||
let mask = document.querySelector('.el-loading-mask');
|
let mask = document.querySelector('.el-loading-mask');
|
||||||
|
let container = document.querySelector('.loading-container');
|
||||||
expect(mask).to.exist;
|
expect(mask).to.exist;
|
||||||
expect(mask.parentNode).to.equal(document.querySelector('.loading-container'));
|
expect(mask.parentNode).to.equal(container);
|
||||||
|
loadingInstance.close();
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(container.style.position).to.equal('relative');
|
||||||
|
done();
|
||||||
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('body', () => {
|
it('body', () => {
|
||||||
|
|
|
@ -219,6 +219,7 @@ describe('Pagination', () => {
|
||||||
triggerEvent(input, 'change');
|
triggerEvent(input, 'change');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(vm.page).to.equal(10);
|
expect(vm.page).to.equal(10);
|
||||||
|
expect(input.value).to.equal('10');
|
||||||
|
|
||||||
input.value = '我好帅';
|
input.value = '我好帅';
|
||||||
triggerEvent(input, 'change');
|
triggerEvent(input, 'change');
|
||||||
|
|
|
@ -95,6 +95,40 @@ describe('Rate', () => {
|
||||||
expect(thirdIcon.style.color).to.equal('rgb(255, 153, 0)');
|
expect(thirdIcon.style.color).to.equal('rgb(255, 153, 0)');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('colors are updated after prop is changed', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
|
<el-rate v-model="value" :colors="colors"></el-rate>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
colors() {
|
||||||
|
if (this.muted) {
|
||||||
|
return ['#999', '#999', '#999'];
|
||||||
|
} else {
|
||||||
|
return ['#99A9BF', '#F7BA2A', '#FF9900'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: 4,
|
||||||
|
muted: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
setTimeout(() => {
|
||||||
|
vm.muted = true;
|
||||||
|
vm.$nextTick(() => {
|
||||||
|
const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon');
|
||||||
|
expect(thirdIcon.style.color).to.equal('rgb(153, 153, 153)');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 10);
|
||||||
|
});
|
||||||
|
|
||||||
it('threshold', () => {
|
it('threshold', () => {
|
||||||
vm = createVue({
|
vm = createVue({
|
||||||
template: `
|
template: `
|
||||||
|
|
|
@ -572,8 +572,9 @@ describe('Select', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
|
|
||||||
expect(vm.value.length).to.equal(2);
|
expect(vm.value.length).to.equal(2);
|
||||||
|
setTimeout(() => {
|
||||||
|
const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
|
||||||
tagCloseIcons[1].click();
|
tagCloseIcons[1].click();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(vm.value.length).to.equal(1);
|
expect(vm.value.length).to.equal(1);
|
||||||
|
@ -584,8 +585,9 @@ describe('Select', () => {
|
||||||
expect(window.console.log.callCount).to.equal(2);
|
expect(window.console.log.callCount).to.equal(2);
|
||||||
window.console.log.restore();
|
window.console.log.restore();
|
||||||
done();
|
done();
|
||||||
}, 100);
|
}, 50);
|
||||||
}, 100);
|
}, 50);
|
||||||
|
}, 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('multiple limit', done => {
|
it('multiple limit', done => {
|
||||||
|
|
Loading…
Reference in New Issue