evui 3.3.0 → 3.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/evui.common.js +633 -555
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +633 -555
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.vue +16 -0
- package/src/components/chart/Chart.vue +25 -9
- package/src/components/chart/chart.core.js +24 -1
- package/src/components/chart/element/element.tip.js +23 -11
- package/src/components/chart/model/model.store.js +89 -31
- package/src/components/chart/plugins/plugins.interaction.js +14 -118
- package/src/components/chart/uses.js +8 -2
- package/src/components/grid/Grid.vue +5 -2
- package/src/components/grid/style/grid.scss +1 -1
- package/src/components/grid/uses.js +64 -51
- package/src/components/messageBox/MessageBox.vue +35 -6
- package/src/components/treeGrid/TreeGrid.vue +6 -4
- package/src/components/treeGrid/style/treeGrid.scss +1 -1
- package/src/components/treeGrid/uses.js +41 -35
- package/src/components/window/uses.js +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getCurrentInstance } from 'vue';
|
|
1
|
+
import { getCurrentInstance, nextTick } from 'vue';
|
|
2
2
|
import { isEqual, uniqBy } from 'lodash-es';
|
|
3
3
|
import { numberWithComma } from '@/common/utils';
|
|
4
4
|
|
|
@@ -75,23 +75,25 @@ export const scrollEvent = (params) => {
|
|
|
75
75
|
const updateVScroll = () => {
|
|
76
76
|
const bodyEl = elementInfo.body;
|
|
77
77
|
const rowHeight = resizeInfo.rowHeight;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
firstVisibleIndex
|
|
84
|
-
|
|
78
|
+
if (bodyEl) {
|
|
79
|
+
const rowCount = bodyEl.clientHeight > rowHeight
|
|
80
|
+
? Math.ceil(bodyEl.clientHeight / rowHeight) : stores.store.length;
|
|
81
|
+
const totalScrollHeight = stores.store.length * rowHeight;
|
|
82
|
+
let firstVisibleIndex = Math.floor(bodyEl.scrollTop / rowHeight);
|
|
83
|
+
if (firstVisibleIndex > stores.store.length - 1) {
|
|
84
|
+
firstVisibleIndex = 0;
|
|
85
|
+
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const lastVisibleIndex = firstVisibleIndex + rowCount;
|
|
88
|
+
const firstIndex = Math.max(firstVisibleIndex, 0);
|
|
89
|
+
const lastIndex = lastVisibleIndex;
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
stores.viewStore = stores.store.slice(firstIndex, lastIndex);
|
|
92
|
+
scrollInfo.hasVerticalScrollBar = rowCount < stores.store.length;
|
|
93
|
+
scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
|
|
94
|
+
scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
|
|
95
|
+
- scrollInfo.vScrollTopHeight;
|
|
96
|
+
}
|
|
95
97
|
};
|
|
96
98
|
/**
|
|
97
99
|
* 수평 스크롤의 위치 계산 후 적용한다.
|
|
@@ -114,7 +116,7 @@ export const scrollEvent = (params) => {
|
|
|
114
116
|
const isHorizontal = !(scrollLeft === lastLeft);
|
|
115
117
|
const isVertical = !(scrollTop === lastTop);
|
|
116
118
|
|
|
117
|
-
if (isVertical && bodyEl
|
|
119
|
+
if (isVertical && bodyEl?.clientHeight) {
|
|
118
120
|
updateVScroll();
|
|
119
121
|
}
|
|
120
122
|
|
|
@@ -223,22 +225,24 @@ export const resizeEvent = (params) => {
|
|
|
223
225
|
* grid resize 이벤트를 처리한다.
|
|
224
226
|
*/
|
|
225
227
|
const onResize = () => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
228
|
+
nextTick(() => {
|
|
229
|
+
if (resizeInfo.adjust) {
|
|
230
|
+
stores.orderedColumns.map((column) => {
|
|
231
|
+
const item = column;
|
|
229
232
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
if (!props.columns[column.index].width && !item.resized) {
|
|
234
|
+
item.width = 0;
|
|
235
|
+
}
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
return item;
|
|
238
|
+
}, this);
|
|
239
|
+
}
|
|
237
240
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
calculatedColumn();
|
|
242
|
+
if (elementInfo.body?.clientHeight) {
|
|
243
|
+
updateVScroll();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
242
246
|
};
|
|
243
247
|
|
|
244
248
|
const onShow = (isVisible) => {
|
|
@@ -496,21 +500,32 @@ export const sortEvent = (params) => {
|
|
|
496
500
|
const index = getColumnIndex(sortInfo.sortField);
|
|
497
501
|
const type = props.columns[index]?.type || 'string';
|
|
498
502
|
const sortFn = sortInfo.sortOrder === 'desc' ? setDesc : setAsc;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
503
|
+
switch (type) {
|
|
504
|
+
case 'string':
|
|
505
|
+
stores.store.sort((a, b) => {
|
|
506
|
+
if (typeof a[ROW_DATA_INDEX][index] === 'string') {
|
|
507
|
+
return sortFn(a[ROW_DATA_INDEX][index]?.toLowerCase(),
|
|
508
|
+
b[ROW_DATA_INDEX][index]?.toLowerCase());
|
|
509
|
+
}
|
|
510
|
+
return 0;
|
|
511
|
+
});
|
|
512
|
+
break;
|
|
513
|
+
case 'stringNumber':
|
|
514
|
+
stores.store.sort((a, b) => {
|
|
515
|
+
if (typeof a[ROW_DATA_INDEX][index] === 'string' || typeof a[ROW_DATA_INDEX][index] === 'number') {
|
|
516
|
+
return sortFn(Number(a[ROW_DATA_INDEX][index]), Number(b[ROW_DATA_INDEX][index]));
|
|
517
|
+
}
|
|
518
|
+
return 0;
|
|
519
|
+
});
|
|
520
|
+
break;
|
|
521
|
+
default:
|
|
522
|
+
stores.store.sort((a, b) => {
|
|
523
|
+
if (typeof a[ROW_DATA_INDEX][index] === 'number' || typeof a[ROW_DATA_INDEX][index] === 'boolean') {
|
|
524
|
+
return sortFn(a[ROW_DATA_INDEX][index], b[ROW_DATA_INDEX][index]);
|
|
525
|
+
}
|
|
526
|
+
return 0;
|
|
527
|
+
});
|
|
528
|
+
break;
|
|
514
529
|
}
|
|
515
530
|
};
|
|
516
531
|
return { onSort, setSort };
|
|
@@ -736,14 +751,12 @@ export const filterEvent = (params) => {
|
|
|
736
751
|
}
|
|
737
752
|
const store = stores.store;
|
|
738
753
|
let checkedCount = 0;
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
754
|
+
store.forEach((row) => {
|
|
755
|
+
row[ROW_CHECK_INDEX] = checkInfo.checkedRows.includes(row[ROW_DATA_INDEX]);
|
|
756
|
+
if (row[ROW_CHECK_INDEX]) {
|
|
742
757
|
checkedCount += 1;
|
|
743
|
-
} else {
|
|
744
|
-
store[ix][ROW_CHECK_INDEX] = false;
|
|
745
758
|
}
|
|
746
|
-
}
|
|
759
|
+
});
|
|
747
760
|
if (store.length && store.length === checkedCount) {
|
|
748
761
|
checkInfo.isHeaderChecked = true;
|
|
749
762
|
} else {
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
ref="msgRef"
|
|
15
15
|
class="ev-message-box"
|
|
16
16
|
:class="{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
[`type-${type}`]: !!type,
|
|
18
|
+
'show-close': showClose,
|
|
19
|
+
'has-icon': !!iconClass,
|
|
20
|
+
'has-title': !!title,
|
|
21
|
+
}"
|
|
22
|
+
tabindex="-1"
|
|
22
23
|
>
|
|
23
24
|
<span
|
|
24
25
|
v-if="iconClass"
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
v-if="showCancelBtn"
|
|
53
54
|
size="small"
|
|
54
55
|
class="ev-message-box-cancel"
|
|
56
|
+
:auto-focus="hasFocus('cancelBtn')"
|
|
55
57
|
@click="closeMsg('cancel')"
|
|
56
58
|
>
|
|
57
59
|
{{ cancelBtnText }}
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
type="primary"
|
|
62
64
|
size="small"
|
|
63
65
|
class="ev-message-box-confirm"
|
|
66
|
+
:auto-focus="hasFocus('confirmBtn')"
|
|
64
67
|
@click="closeMsg('ok')"
|
|
65
68
|
>
|
|
66
69
|
{{ confirmBtnText }}
|
|
@@ -80,7 +83,7 @@
|
|
|
80
83
|
</template>
|
|
81
84
|
|
|
82
85
|
<script>
|
|
83
|
-
import { reactive, toRefs, watch, onMounted } from 'vue';
|
|
86
|
+
import { reactive, toRefs, watch, onMounted, ref } from 'vue';
|
|
84
87
|
import EvButton from '@/components/button/Button.vue';
|
|
85
88
|
|
|
86
89
|
export default {
|
|
@@ -142,8 +145,14 @@ export default {
|
|
|
142
145
|
type: Function,
|
|
143
146
|
default: null,
|
|
144
147
|
},
|
|
148
|
+
focusable: {
|
|
149
|
+
type: Boolean,
|
|
150
|
+
default: false,
|
|
151
|
+
},
|
|
145
152
|
},
|
|
146
153
|
setup(props) {
|
|
154
|
+
const msgRef = ref(null);
|
|
155
|
+
|
|
147
156
|
const state = reactive({
|
|
148
157
|
isShow: true,
|
|
149
158
|
iconClass: '',
|
|
@@ -190,9 +199,27 @@ export default {
|
|
|
190
199
|
}
|
|
191
200
|
};
|
|
192
201
|
|
|
202
|
+
const hasFocus = (type) => {
|
|
203
|
+
if (!props.focusable) return false;
|
|
204
|
+
|
|
205
|
+
switch (type) {
|
|
206
|
+
case 'confirmBtn':
|
|
207
|
+
return props.showConfirmBtn;
|
|
208
|
+
case 'cancelBtn':
|
|
209
|
+
return !props.showConfirmBtn && props.showCancelBtn;
|
|
210
|
+
case 'messagebox':
|
|
211
|
+
return !props.showConfirmBtn && !props.showCancelBtn;
|
|
212
|
+
default:
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
193
217
|
onMounted(() => {
|
|
194
218
|
setState();
|
|
195
219
|
document.addEventListener('keydown', keydown);
|
|
220
|
+
if (hasFocus('messagebox')) {
|
|
221
|
+
msgRef.value.focus();
|
|
222
|
+
}
|
|
196
223
|
});
|
|
197
224
|
watch(() => state.isShow, (val) => {
|
|
198
225
|
if (!val) {
|
|
@@ -202,6 +229,8 @@ export default {
|
|
|
202
229
|
return {
|
|
203
230
|
closeMsg,
|
|
204
231
|
...toRefs(state),
|
|
232
|
+
msgRef,
|
|
233
|
+
hasFocus,
|
|
205
234
|
};
|
|
206
235
|
},
|
|
207
236
|
};
|
|
@@ -332,13 +332,13 @@ export default {
|
|
|
332
332
|
|
|
333
333
|
const {
|
|
334
334
|
onSearch,
|
|
335
|
-
} = filterEvent({ checkInfo, stores, getConvertValue,
|
|
335
|
+
} = filterEvent({ checkInfo, stores, getConvertValue, onResize });
|
|
336
336
|
|
|
337
337
|
onMounted(() => {
|
|
338
338
|
stores.treeStore = setTreeNodeStore();
|
|
339
339
|
});
|
|
340
340
|
onActivated(() => {
|
|
341
|
-
|
|
341
|
+
onResize();
|
|
342
342
|
});
|
|
343
343
|
watch(
|
|
344
344
|
() => props.checked,
|
|
@@ -377,7 +377,6 @@ export default {
|
|
|
377
377
|
stores.treeRows = newData;
|
|
378
378
|
stores.treeStore = setTreeNodeStore();
|
|
379
379
|
onResize();
|
|
380
|
-
updateVScroll();
|
|
381
380
|
}, { deep: true },
|
|
382
381
|
);
|
|
383
382
|
watch(
|
|
@@ -400,7 +399,10 @@ export default {
|
|
|
400
399
|
watch(
|
|
401
400
|
() => searchValue.value,
|
|
402
401
|
(value) => {
|
|
403
|
-
|
|
402
|
+
const searchWord = value?.value ?? value;
|
|
403
|
+
if (searchWord) {
|
|
404
|
+
onSearch(searchWord);
|
|
405
|
+
}
|
|
404
406
|
}, { immediate: true },
|
|
405
407
|
);
|
|
406
408
|
const gridStyle = computed(() => ({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCurrentInstance, nextTick } from 'vue';
|
|
2
|
+
import { cloneDeep } from 'lodash-es';
|
|
2
3
|
import { numberWithComma } from '@/common/utils';
|
|
3
4
|
|
|
4
5
|
export const commonFunctions = () => {
|
|
@@ -70,24 +71,26 @@ export const scrollEvent = (params) => {
|
|
|
70
71
|
const updateVScroll = () => {
|
|
71
72
|
const store = stores.showTreeStore;
|
|
72
73
|
const bodyEl = elementInfo.body;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
firstVisibleIndex
|
|
80
|
-
|
|
74
|
+
if (bodyEl) {
|
|
75
|
+
const rowHeight = resizeInfo.rowHeight;
|
|
76
|
+
const rowCount = bodyEl.clientHeight > rowHeight
|
|
77
|
+
? Math.ceil(bodyEl.clientHeight / rowHeight) : store.length;
|
|
78
|
+
const totalScrollHeight = store.length * rowHeight;
|
|
79
|
+
let firstVisibleIndex = Math.floor(bodyEl.scrollTop / rowHeight);
|
|
80
|
+
if (firstVisibleIndex > store.length - 1) {
|
|
81
|
+
firstVisibleIndex = 0;
|
|
82
|
+
}
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
const lastVisibleIndex = firstVisibleIndex + rowCount;
|
|
85
|
+
const firstIndex = Math.max(firstVisibleIndex, 0);
|
|
86
|
+
const lastIndex = lastVisibleIndex;
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
stores.viewStore = store.slice(firstIndex, lastIndex);
|
|
89
|
+
scrollInfo.hasVerticalScrollBar = rowCount < store.length;
|
|
90
|
+
scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
|
|
91
|
+
scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
|
|
92
|
+
- scrollInfo.vScrollTopHeight;
|
|
93
|
+
}
|
|
91
94
|
};
|
|
92
95
|
/**
|
|
93
96
|
* 수평 스크롤의 위치 계산 후 적용한다.
|
|
@@ -110,7 +113,7 @@ export const scrollEvent = (params) => {
|
|
|
110
113
|
const isHorizontal = !(scrollLeft === lastLeft);
|
|
111
114
|
const isVertical = !(scrollTop === lastTop);
|
|
112
115
|
|
|
113
|
-
if (isVertical) {
|
|
116
|
+
if (isVertical && bodyEl.clientHeight) {
|
|
114
117
|
updateVScroll();
|
|
115
118
|
}
|
|
116
119
|
|
|
@@ -223,22 +226,25 @@ export const resizeEvent = (params) => {
|
|
|
223
226
|
/**
|
|
224
227
|
* grid resize 이벤트를 처리한다.
|
|
225
228
|
*/
|
|
226
|
-
const onResize =
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
const onResize = () => {
|
|
230
|
+
nextTick(() => {
|
|
231
|
+
if (resizeInfo.adjust) {
|
|
232
|
+
stores.orderedColumns.map((column) => {
|
|
233
|
+
const item = column;
|
|
234
|
+
|
|
235
|
+
if (!props.columns[column.index].width && !item.resized) {
|
|
236
|
+
item.width = 0;
|
|
237
|
+
}
|
|
235
238
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
+
return item;
|
|
240
|
+
}, this);
|
|
241
|
+
}
|
|
239
242
|
|
|
240
|
-
|
|
241
|
-
|
|
243
|
+
calculatedColumn();
|
|
244
|
+
if (elementInfo.body?.clientHeight) {
|
|
245
|
+
updateVScroll();
|
|
246
|
+
}
|
|
247
|
+
});
|
|
242
248
|
};
|
|
243
249
|
const onShow = (isVisible) => {
|
|
244
250
|
if (isVisible) {
|
|
@@ -603,11 +609,12 @@ export const treeEvent = (params) => {
|
|
|
603
609
|
|
|
604
610
|
nodeList.push(node);
|
|
605
611
|
|
|
606
|
-
if (
|
|
612
|
+
if (!Object.hasOwnProperty.call(node, 'parent')) {
|
|
607
613
|
node.parent = parent;
|
|
608
614
|
}
|
|
609
615
|
if (node.children) {
|
|
610
616
|
node.hasChild = true;
|
|
617
|
+
node.children = cloneDeep(node.children);
|
|
611
618
|
node.children.forEach(child =>
|
|
612
619
|
setNodeData({
|
|
613
620
|
node: child,
|
|
@@ -648,7 +655,7 @@ export const treeEvent = (params) => {
|
|
|
648
655
|
};
|
|
649
656
|
|
|
650
657
|
export const filterEvent = (params) => {
|
|
651
|
-
const { checkInfo, stores, getConvertValue,
|
|
658
|
+
const { checkInfo, stores, getConvertValue, onResize } = params;
|
|
652
659
|
const makeParentShow = (data) => {
|
|
653
660
|
if (!data?.parent) {
|
|
654
661
|
return;
|
|
@@ -735,8 +742,7 @@ export const filterEvent = (params) => {
|
|
|
735
742
|
}
|
|
736
743
|
const isCheck = store.length > 0 && store.every(n => n.checked === true);
|
|
737
744
|
checkInfo.isHeaderChecked = isCheck;
|
|
738
|
-
|
|
739
|
-
updateVScroll();
|
|
745
|
+
onResize();
|
|
740
746
|
}, 500);
|
|
741
747
|
};
|
|
742
748
|
return { onSearch };
|
|
@@ -433,8 +433,8 @@ const useMouseEvent = (param) => {
|
|
|
433
433
|
setDragStyle({
|
|
434
434
|
top: `${tempTop}px`,
|
|
435
435
|
left: `${tempLeft}px`,
|
|
436
|
-
width: props.width,
|
|
437
|
-
height: props.height,
|
|
436
|
+
width: dragStyle.width ?? props.width,
|
|
437
|
+
height: dragStyle.height ?? props.height,
|
|
438
438
|
});
|
|
439
439
|
} else if (props.resizable && clickedInfo.pressedSpot === 'border') {
|
|
440
440
|
resizeWindow(e);
|