evui 3.1.41 → 3.1.45
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 +1289 -556
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +1289 -556
- 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/calendar/Calendar.vue +194 -82
- package/src/components/calendar/uses.js +457 -138
- package/src/components/datePicker/DatePicker.vue +109 -31
- package/src/components/datePicker/uses.js +219 -21
- package/src/components/treeGrid/TreeGrid.vue +24 -2
- package/src/components/treeGrid/TreeGridNode.vue +10 -1
- package/src/components/treeGrid/treeGrid.toolbar.vue +4 -4
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
v-clickoutside="clickOutsideDropbox"
|
|
5
5
|
class="ev-date-picker"
|
|
6
6
|
:class="{
|
|
7
|
-
disabled,
|
|
7
|
+
disabled : $props.disabled,
|
|
8
8
|
}"
|
|
9
9
|
>
|
|
10
|
-
<template v-if="mode === 'date' || mode === 'dateTime'">
|
|
10
|
+
<template v-if="$props.mode === 'date' || $props.mode === 'dateTime'">
|
|
11
11
|
<span class="ev-date-picker-prefix-icon">
|
|
12
12
|
<i class="ev-icon-calendar" />
|
|
13
13
|
</span>
|
|
@@ -15,15 +15,18 @@
|
|
|
15
15
|
v-model.trim="currentValue"
|
|
16
16
|
type="text"
|
|
17
17
|
class="ev-input"
|
|
18
|
-
:placeholder="placeholder"
|
|
19
|
-
:disabled="disabled"
|
|
18
|
+
:placeholder="$props.placeholder"
|
|
19
|
+
:disabled="$props.disabled"
|
|
20
20
|
@click="clickSelectInput"
|
|
21
21
|
@keydown.enter.prevent="validateValue(currentValue)"
|
|
22
22
|
@change="validateValue(currentValue)"
|
|
23
23
|
/>
|
|
24
24
|
</template>
|
|
25
25
|
<template v-else>
|
|
26
|
-
<div
|
|
26
|
+
<div
|
|
27
|
+
class="ev-date-picker-tag-wrapper"
|
|
28
|
+
@click="clickSelectInput"
|
|
29
|
+
>
|
|
27
30
|
<span class="ev-date-picker-prefix-icon">
|
|
28
31
|
<i class="ev-icon-calendar" />
|
|
29
32
|
</span>
|
|
@@ -31,23 +34,22 @@
|
|
|
31
34
|
type="text"
|
|
32
35
|
class="ev-input readonly"
|
|
33
36
|
readonly
|
|
34
|
-
:placeholder="placeholder"
|
|
35
|
-
:disabled="disabled"
|
|
36
|
-
@click="clickSelectInput"
|
|
37
|
+
:placeholder="$props.placeholder"
|
|
38
|
+
:disabled="$props.disabled"
|
|
37
39
|
/>
|
|
38
40
|
<template
|
|
39
|
-
v-if="mode === 'dateMulti'
|
|
40
|
-
&& (options.multiType === 'date' ||
|
|
41
|
+
v-if="$props.mode === 'dateMulti'
|
|
42
|
+
&& ($props.options.multiType === 'date' || !$props.options.tagShorten)"
|
|
41
43
|
>
|
|
42
44
|
<div
|
|
43
45
|
v-for="(item, idx) in mv"
|
|
44
46
|
:key="`${item}_${idx}`"
|
|
45
47
|
class="ev-select-tag"
|
|
46
|
-
:class="{ num: options.multiType !== 'date' }"
|
|
48
|
+
:class="{ num: $props.options.multiType !== 'date' }"
|
|
47
49
|
>
|
|
48
50
|
<span class="ev-tag-name"> {{ item }} </span>
|
|
49
51
|
<span
|
|
50
|
-
v-if="options.multiType === 'date'"
|
|
52
|
+
v-if="$props.options.multiType === 'date'"
|
|
51
53
|
class="ev-tag-suffix"
|
|
52
54
|
@click.stop="[removeMv(item), changeDropboxPosition()]"
|
|
53
55
|
>
|
|
@@ -68,7 +70,7 @@
|
|
|
68
70
|
</template>
|
|
69
71
|
</div>
|
|
70
72
|
</template>
|
|
71
|
-
<template v-if="clearable">
|
|
73
|
+
<template v-if="$props.clearable">
|
|
72
74
|
<span
|
|
73
75
|
v-show="isClearableIcon"
|
|
74
76
|
class="ev-input-suffix"
|
|
@@ -82,17 +84,38 @@
|
|
|
82
84
|
v-if="isDropbox"
|
|
83
85
|
ref="dropbox"
|
|
84
86
|
class="ev-date-picker-dropdown"
|
|
85
|
-
:class="mode"
|
|
87
|
+
:class="$props.mode"
|
|
86
88
|
:style="dropboxPosition"
|
|
87
89
|
>
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
<div
|
|
91
|
+
v-if="usedShortcuts.length"
|
|
92
|
+
class="ev-date-picker-dropbox__button-layout">
|
|
93
|
+
<ev-button-group>
|
|
94
|
+
<ev-button
|
|
95
|
+
v-for="button in usedShortcuts"
|
|
96
|
+
:key="button.key"
|
|
97
|
+
:type="button.isActive ? 'primary' : 'default'"
|
|
98
|
+
@click="clickShortcut(button.key)"
|
|
99
|
+
>
|
|
100
|
+
{{ button.label }}
|
|
101
|
+
</ev-button>
|
|
102
|
+
</ev-button-group>
|
|
103
|
+
</div>
|
|
104
|
+
<div
|
|
105
|
+
v-if="usedShortcuts.length"
|
|
106
|
+
class="ev-date-picker-dropbox__divider"
|
|
95
107
|
/>
|
|
108
|
+
<div
|
|
109
|
+
:class="{ 'ev-date-picker-dropbox__calendar':usedShortcuts.length }">
|
|
110
|
+
<ev-calendar
|
|
111
|
+
key="fromCalendar"
|
|
112
|
+
v-model="mv"
|
|
113
|
+
:mode="$props.mode"
|
|
114
|
+
:month-notation="$props.monthNotation"
|
|
115
|
+
:day-of-the-week-notation="$props.dayOfTheWeekNotation"
|
|
116
|
+
:options="$props.options"
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
96
119
|
</div>
|
|
97
120
|
</div>
|
|
98
121
|
</div>
|
|
@@ -100,7 +123,7 @@
|
|
|
100
123
|
|
|
101
124
|
<script>
|
|
102
125
|
import { datePickerClickoutside as clickoutside } from '@/directives/clickoutside';
|
|
103
|
-
import { useModel, useDropdown } from './uses';
|
|
126
|
+
import { useModel, useDropdown, useShortcuts } from './uses';
|
|
104
127
|
|
|
105
128
|
export default {
|
|
106
129
|
name: 'EvDatePicker',
|
|
@@ -116,7 +139,8 @@ export default {
|
|
|
116
139
|
const dateTimeReg = new RegExp(/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]/);
|
|
117
140
|
if (Array.isArray(value)) {
|
|
118
141
|
return value.every(v => !!(!v
|
|
119
|
-
|
|
142
|
+
|| (v.length === 10 && dateReg.exec(v)))
|
|
143
|
+
|| (v.length === 19 && dateTimeReg.exec(v)));
|
|
120
144
|
}
|
|
121
145
|
return !!(!value
|
|
122
146
|
|| (value.length === 10 && dateReg.exec(value))
|
|
@@ -138,7 +162,7 @@ export default {
|
|
|
138
162
|
mode: {
|
|
139
163
|
type: String,
|
|
140
164
|
default: 'date',
|
|
141
|
-
validator: value => ['date', 'dateTime', 'dateMulti', 'dateRange']
|
|
165
|
+
validator: value => ['date', 'dateTime', 'dateMulti', 'dateRange', 'dateTimeRange']
|
|
142
166
|
.indexOf(value) !== -1,
|
|
143
167
|
},
|
|
144
168
|
monthNotation: {
|
|
@@ -160,11 +184,33 @@ export default {
|
|
|
160
184
|
limit: 1,
|
|
161
185
|
tagShorten: false,
|
|
162
186
|
}),
|
|
163
|
-
validator: ({ multiType, multiDayLimit, disabledDate, tagShorten }) =>
|
|
164
|
-
|
|
187
|
+
validator: ({ multiType, multiDayLimit, disabledDate, tagShorten, timeFormat }) => {
|
|
188
|
+
const timeReg = new RegExp(/(HH|2[0-3]|[01][0-9]):(mm|[0-5][0-9]):(ss|[0-5][0-9])/);
|
|
189
|
+
return (multiType ? ['weekday', 'week', 'date'].indexOf(multiType) !== -1 : true)
|
|
165
190
|
&& (multiDayLimit ? typeof multiDayLimit === 'number' && multiDayLimit > 0 : true)
|
|
166
191
|
&& (disabledDate ? typeof disabledDate === 'function' : true)
|
|
167
|
-
&& (tagShorten !== undefined ? typeof tagShorten === 'boolean' : true)
|
|
192
|
+
&& (tagShorten !== undefined ? typeof tagShorten === 'boolean' : true)
|
|
193
|
+
&& Array.isArray(timeFormat)
|
|
194
|
+
? timeFormat.every(v => !!(!v || timeReg.exec(v)))
|
|
195
|
+
: !!(!timeFormat || (timeReg.exec(timeFormat)));
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
shortcuts: {
|
|
199
|
+
type: Array,
|
|
200
|
+
default: () => [],
|
|
201
|
+
validator: (value) => {
|
|
202
|
+
if (!value.length) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
return value.every(({ shortcutDate }) => {
|
|
206
|
+
if (typeof shortcutDate !== 'function') {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
const date = shortcutDate();
|
|
210
|
+
return (Array.isArray(date) && date.every(d => d instanceof Date) && date[0] <= date[1])
|
|
211
|
+
|| (typeof date === 'object' && date instanceof Date);
|
|
212
|
+
});
|
|
213
|
+
},
|
|
168
214
|
},
|
|
169
215
|
},
|
|
170
216
|
emits: {
|
|
@@ -190,10 +236,20 @@ export default {
|
|
|
190
236
|
clickSelectInput,
|
|
191
237
|
clickOutsideDropbox,
|
|
192
238
|
changeDropboxPosition,
|
|
193
|
-
} = useDropdown(
|
|
239
|
+
} = useDropdown();
|
|
240
|
+
|
|
241
|
+
const {
|
|
242
|
+
usedShortcuts,
|
|
243
|
+
clickShortcut,
|
|
244
|
+
setActiveShortcut,
|
|
245
|
+
} = useShortcuts({
|
|
246
|
+
mv,
|
|
194
247
|
currentValue,
|
|
248
|
+
clickOutsideDropbox,
|
|
195
249
|
});
|
|
196
250
|
|
|
251
|
+
setActiveShortcut();
|
|
252
|
+
|
|
197
253
|
return {
|
|
198
254
|
mv,
|
|
199
255
|
currentValue,
|
|
@@ -211,6 +267,9 @@ export default {
|
|
|
211
267
|
clickSelectInput,
|
|
212
268
|
clickOutsideDropbox,
|
|
213
269
|
changeDropboxPosition,
|
|
270
|
+
|
|
271
|
+
usedShortcuts,
|
|
272
|
+
clickShortcut,
|
|
214
273
|
};
|
|
215
274
|
},
|
|
216
275
|
};
|
|
@@ -311,6 +370,7 @@ export default {
|
|
|
311
370
|
|
|
312
371
|
&.num {
|
|
313
372
|
padding-right: 8px;
|
|
373
|
+
cursor: pointer;
|
|
314
374
|
}
|
|
315
375
|
|
|
316
376
|
.ev-tag-suffix {
|
|
@@ -329,8 +389,26 @@ export default {
|
|
|
329
389
|
}
|
|
330
390
|
}
|
|
331
391
|
|
|
332
|
-
.ev-date-picker-dropbox
|
|
333
|
-
|
|
334
|
-
|
|
392
|
+
.ev-date-picker-dropbox {
|
|
393
|
+
&-wrapper {
|
|
394
|
+
height: 0;
|
|
395
|
+
z-index: 100;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
&__button-layout {
|
|
399
|
+
margin: 5px;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
&__divider {
|
|
403
|
+
width: 100%;
|
|
404
|
+
height: 2px;
|
|
405
|
+
margin: 8px 0;
|
|
406
|
+
background-color: #E5E5E5;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
&__calendar {
|
|
410
|
+
height: 100%;
|
|
411
|
+
margin: 5px;
|
|
412
|
+
}
|
|
335
413
|
}
|
|
336
414
|
</style>
|
|
@@ -2,12 +2,14 @@ import {
|
|
|
2
2
|
ref, reactive, computed, watch,
|
|
3
3
|
nextTick, getCurrentInstance,
|
|
4
4
|
} from 'vue';
|
|
5
|
+
import { getChangedValueByTimeFormat } from '../calendar/uses';
|
|
5
6
|
|
|
6
7
|
const dateReg = new RegExp(/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/);
|
|
7
8
|
const dateTimeReg = new RegExp(/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]/);
|
|
8
9
|
|
|
9
10
|
export const useModel = () => {
|
|
10
11
|
const { props, emit } = getCurrentInstance();
|
|
12
|
+
const timeFormat = props.options?.timeFormat;
|
|
11
13
|
|
|
12
14
|
// Select 컴포넌트의 v-model 값
|
|
13
15
|
const mv = computed({
|
|
@@ -15,13 +17,42 @@ export const useModel = () => {
|
|
|
15
17
|
if (!props.modelValue) {
|
|
16
18
|
return (props.mode === 'date' || props.mode === 'dateTime') ? '' : [];
|
|
17
19
|
}
|
|
20
|
+
if (['dateTime', 'dateTimeRange'].includes(props.mode) && timeFormat) {
|
|
21
|
+
if (props.mode === 'dateTime') {
|
|
22
|
+
return getChangedValueByTimeFormat(timeFormat, props.modelValue);
|
|
23
|
+
} else if (props.modelValue.length) {
|
|
24
|
+
const [fromTimeFormat, toTimeFormat] = timeFormat;
|
|
25
|
+
return [
|
|
26
|
+
getChangedValueByTimeFormat(fromTimeFormat, props.modelValue[0]),
|
|
27
|
+
getChangedValueByTimeFormat(toTimeFormat, props.modelValue[1]),
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
18
31
|
return props.modelValue;
|
|
19
32
|
},
|
|
20
33
|
set: value => emit('update:modelValue', value),
|
|
21
34
|
});
|
|
22
35
|
|
|
23
36
|
// mode: 'date' or 'dateTime'시 input box의 입력된 텍스트값
|
|
24
|
-
|
|
37
|
+
let currentValue;
|
|
38
|
+
if (['dateTimeRange', 'dateTime'].includes(props.mode) && timeFormat) {
|
|
39
|
+
if (props.mode === 'dateTimeRange' && props.modelValue.length) {
|
|
40
|
+
const [fromDate, toDate] = props.modelValue;
|
|
41
|
+
const [fromTimeFormat, toTimeFormat] = timeFormat;
|
|
42
|
+
|
|
43
|
+
props.modelValue = [
|
|
44
|
+
getChangedValueByTimeFormat(fromTimeFormat, fromDate),
|
|
45
|
+
getChangedValueByTimeFormat(toTimeFormat, toDate),
|
|
46
|
+
];
|
|
47
|
+
currentValue = ref(props.modelValue);
|
|
48
|
+
} else if (props.mode === 'dateTime' && props.modelValue) {
|
|
49
|
+
currentValue = ref(getChangedValueByTimeFormat(timeFormat, props.modelValue));
|
|
50
|
+
} else {
|
|
51
|
+
currentValue = ref(props.modelValue);
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
currentValue = ref(props.modelValue);
|
|
55
|
+
}
|
|
25
56
|
|
|
26
57
|
const validateValue = (curr) => {
|
|
27
58
|
if (props.mode === 'date'
|
|
@@ -89,9 +120,8 @@ export const useModel = () => {
|
|
|
89
120
|
};
|
|
90
121
|
};
|
|
91
122
|
|
|
92
|
-
export const useDropdown = (
|
|
123
|
+
export const useDropdown = () => {
|
|
93
124
|
const { props } = getCurrentInstance();
|
|
94
|
-
const { currentValue } = param;
|
|
95
125
|
|
|
96
126
|
const isDropbox = ref(false);
|
|
97
127
|
const datePicker = ref(null);
|
|
@@ -162,24 +192,6 @@ export const useDropdown = (param) => {
|
|
|
162
192
|
isDropbox.value = false;
|
|
163
193
|
};
|
|
164
194
|
|
|
165
|
-
watch(
|
|
166
|
-
() => props.modelValue,
|
|
167
|
-
(curr) => {
|
|
168
|
-
if (props.mode === 'dateMulti'
|
|
169
|
-
&& props?.options?.multiType === 'date'
|
|
170
|
-
&& props?.options?.multiDayLimit > curr.length
|
|
171
|
-
) {
|
|
172
|
-
return;
|
|
173
|
-
} else if (props.mode === 'dateTime') {
|
|
174
|
-
currentValue.value = curr;
|
|
175
|
-
return;
|
|
176
|
-
} else if (props.mode === 'date') {
|
|
177
|
-
currentValue.value = curr;
|
|
178
|
-
}
|
|
179
|
-
clickOutsideDropbox();
|
|
180
|
-
},
|
|
181
|
-
);
|
|
182
|
-
|
|
183
195
|
return {
|
|
184
196
|
isDropbox,
|
|
185
197
|
datePicker,
|
|
@@ -191,3 +203,189 @@ export const useDropdown = (param) => {
|
|
|
191
203
|
changeDropboxPosition,
|
|
192
204
|
};
|
|
193
205
|
};
|
|
206
|
+
|
|
207
|
+
export const useShortcuts = (param) => {
|
|
208
|
+
const { props } = getCurrentInstance();
|
|
209
|
+
const { mv, currentValue, clickOutsideDropbox } = param;
|
|
210
|
+
|
|
211
|
+
const usedShortcuts = reactive([]);
|
|
212
|
+
props.shortcuts?.forEach(({ value, label, shortcutDate }) => {
|
|
213
|
+
usedShortcuts.push({
|
|
214
|
+
key: value,
|
|
215
|
+
label,
|
|
216
|
+
shortcutDate,
|
|
217
|
+
isActive: false,
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* active 되어있는 shortcut 제거
|
|
223
|
+
*/
|
|
224
|
+
const clearShortcuts = () => {
|
|
225
|
+
const targetShortcut = usedShortcuts.find(shortcut => shortcut.isActive);
|
|
226
|
+
if (targetShortcut) {
|
|
227
|
+
targetShortcut.isActive = false;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* targetKey에 해당하는 shortcut을 active
|
|
233
|
+
* @param targetKey
|
|
234
|
+
*/
|
|
235
|
+
const activeShortcut = (targetKey) => {
|
|
236
|
+
const targetShortcut = usedShortcuts.find(shortcut => shortcut.key === targetKey);
|
|
237
|
+
if (targetShortcut) {
|
|
238
|
+
targetShortcut.isActive = true;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* 월, 일을 두자리 숫자로 보정
|
|
244
|
+
* @param num
|
|
245
|
+
* @returns {string|*}
|
|
246
|
+
*/
|
|
247
|
+
const lpadToTwoDigits = (num) => {
|
|
248
|
+
if (num === null) {
|
|
249
|
+
return '00';
|
|
250
|
+
} else if (+num < 10) {
|
|
251
|
+
return `0${num}`;
|
|
252
|
+
}
|
|
253
|
+
return num;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* 'YYYY-MM-DD' 형식으로 format
|
|
258
|
+
* @param targetDate
|
|
259
|
+
* @returns string
|
|
260
|
+
*/
|
|
261
|
+
const formatDate = (targetDate) => {
|
|
262
|
+
const dateValue = targetDate ? new Date(targetDate) : new Date();
|
|
263
|
+
const year = dateValue.getFullYear();
|
|
264
|
+
const month = dateValue.getMonth() + 1;
|
|
265
|
+
const day = dateValue.getDate();
|
|
266
|
+
return `${year}-${lpadToTwoDigits(month)}-${lpadToTwoDigits(day)}`;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 'YYYY-MM-DD HH:mm:ss' 형식으로 format
|
|
271
|
+
* @param targetDateTime
|
|
272
|
+
* @returns string
|
|
273
|
+
*/
|
|
274
|
+
const formatDateTime = (targetDateTime) => {
|
|
275
|
+
const dateTimeValue = targetDateTime ? new Date(targetDateTime) : new Date();
|
|
276
|
+
const hour = dateTimeValue.getHours();
|
|
277
|
+
const min = dateTimeValue.getMinutes();
|
|
278
|
+
const sec = dateTimeValue.getSeconds();
|
|
279
|
+
return `${formatDate(dateTimeValue)} ${lpadToTwoDigits(hour)}:${lpadToTwoDigits(min)}:${lpadToTwoDigits(sec)}`;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* 초기 shortcut 세팅
|
|
284
|
+
* 해당하는 날짜면 active
|
|
285
|
+
*/
|
|
286
|
+
const setActiveShortcut = () => {
|
|
287
|
+
clearShortcuts();
|
|
288
|
+
|
|
289
|
+
const isRange = ['dateRange', 'dateTimeRange'].includes(props.mode);
|
|
290
|
+
|
|
291
|
+
if (!usedShortcuts.length
|
|
292
|
+
|| (props.mode === 'dateMulti' && props.options?.multiType !== 'date')
|
|
293
|
+
|| (isRange && !mv.value.length)
|
|
294
|
+
|| (!isRange && !mv.value)
|
|
295
|
+
) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let targetKey;
|
|
300
|
+
if (isRange) {
|
|
301
|
+
const [fromDate, toDate] = mv.value;
|
|
302
|
+
const targetShortcut = usedShortcuts.find(({ shortcutDate }) => {
|
|
303
|
+
const [sFromDate, sToDate] = shortcutDate();
|
|
304
|
+
const isCorrectFromDate = formatDate(sFromDate) === formatDate(fromDate);
|
|
305
|
+
const isCorrectToDate = formatDate(sToDate) === formatDate(toDate);
|
|
306
|
+
return isCorrectFromDate && isCorrectToDate;
|
|
307
|
+
});
|
|
308
|
+
targetKey = targetShortcut?.key;
|
|
309
|
+
} else {
|
|
310
|
+
const date = formatDate(mv.value);
|
|
311
|
+
const targetShortcut = usedShortcuts.find(({ shortcutDate }) => {
|
|
312
|
+
const sDate = formatDate(shortcutDate());
|
|
313
|
+
return sDate === formatDate(date);
|
|
314
|
+
});
|
|
315
|
+
targetKey = targetShortcut?.key;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (targetKey) {
|
|
319
|
+
activeShortcut(targetKey);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* shortcut을 클릭했을 때 이벤트
|
|
325
|
+
* @param targetKey
|
|
326
|
+
*/
|
|
327
|
+
const clickShortcut = (targetKey) => {
|
|
328
|
+
const isRange = ['dateRange', 'dateTimeRange'].includes(props.mode);
|
|
329
|
+
const targetShortcut = usedShortcuts.find(({ key }) => key === targetKey);
|
|
330
|
+
|
|
331
|
+
if (!targetShortcut) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const shortcutDate = targetShortcut.shortcutDate;
|
|
336
|
+
const timeFormat = props.options?.timeFormat;
|
|
337
|
+
|
|
338
|
+
if (isRange) {
|
|
339
|
+
const [fromDate, toDate] = shortcutDate();
|
|
340
|
+
if (props.mode === 'dateTimeRange') {
|
|
341
|
+
if (timeFormat?.length) {
|
|
342
|
+
const [fromTimeFormat, toTimeFormat] = timeFormat;
|
|
343
|
+
|
|
344
|
+
mv.value = [
|
|
345
|
+
getChangedValueByTimeFormat(fromTimeFormat, formatDateTime(fromDate)),
|
|
346
|
+
getChangedValueByTimeFormat(toTimeFormat, formatDateTime(toDate)),
|
|
347
|
+
];
|
|
348
|
+
} else {
|
|
349
|
+
mv.value = [formatDateTime(fromDate), formatDateTime(toDate)];
|
|
350
|
+
}
|
|
351
|
+
} else {
|
|
352
|
+
mv.value = [formatDate(fromDate), formatDate(toDate)];
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
const sDate = shortcutDate();
|
|
356
|
+
mv.value = props.mode === 'dateTime'
|
|
357
|
+
? getChangedValueByTimeFormat(
|
|
358
|
+
timeFormat,
|
|
359
|
+
formatDateTime(sDate))
|
|
360
|
+
: formatDate(sDate);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
clearShortcuts();
|
|
364
|
+
activeShortcut(targetKey);
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
watch(
|
|
368
|
+
() => props.modelValue,
|
|
369
|
+
(curr) => {
|
|
370
|
+
setActiveShortcut();
|
|
371
|
+
if (props.mode === 'dateMulti'
|
|
372
|
+
&& props?.options?.multiType === 'date'
|
|
373
|
+
&& props?.options?.multiDayLimit > curr.length
|
|
374
|
+
) {
|
|
375
|
+
return;
|
|
376
|
+
} else if (props.mode === 'dateTime' || props.mode === 'dateTimeRange') {
|
|
377
|
+
currentValue.value = curr;
|
|
378
|
+
return;
|
|
379
|
+
} else if (props.mode === 'date') {
|
|
380
|
+
currentValue.value = curr;
|
|
381
|
+
}
|
|
382
|
+
clickOutsideDropbox();
|
|
383
|
+
},
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
return {
|
|
387
|
+
usedShortcuts,
|
|
388
|
+
clickShortcut,
|
|
389
|
+
setActiveShortcut,
|
|
390
|
+
};
|
|
391
|
+
};
|
|
@@ -94,10 +94,10 @@
|
|
|
94
94
|
<table>
|
|
95
95
|
<tbody>
|
|
96
96
|
<tree-grid-node
|
|
97
|
-
v-for="(
|
|
97
|
+
v-for="(node, idx) in viewStore"
|
|
98
98
|
:key="idx"
|
|
99
99
|
:selected-data="selectedRow"
|
|
100
|
-
:node-data="
|
|
100
|
+
:node-data="node"
|
|
101
101
|
:use-checkbox="useCheckbox"
|
|
102
102
|
:ordered-columns="orderedColumns"
|
|
103
103
|
:expand-icon="option.expandIcon"
|
|
@@ -114,6 +114,26 @@
|
|
|
114
114
|
@click-tree-data="onRowClick"
|
|
115
115
|
@dbl-click-tree-data="onRowDblClick"
|
|
116
116
|
>
|
|
117
|
+
<!-- cell renderer -->
|
|
118
|
+
<template
|
|
119
|
+
v-for="(column, cellIndex) in orderedColumns"
|
|
120
|
+
:key="cellIndex"
|
|
121
|
+
v-slot:[getSlotName(column.field)] = "{ item }"
|
|
122
|
+
>
|
|
123
|
+
<template v-if="!!$slots[column.field]">
|
|
124
|
+
<slot
|
|
125
|
+
:name="column.field"
|
|
126
|
+
:item="{
|
|
127
|
+
data: item.data,
|
|
128
|
+
fieldName: column.field
|
|
129
|
+
}"
|
|
130
|
+
>
|
|
131
|
+
</slot>
|
|
132
|
+
</template>
|
|
133
|
+
<template v-else>
|
|
134
|
+
<span :title="node[column.field]">{{node[column.field]}}</span>
|
|
135
|
+
</template>
|
|
136
|
+
</template>
|
|
117
137
|
</tree-grid-node>
|
|
118
138
|
<tr v-if="!viewStore.length">
|
|
119
139
|
<td class="is-empty">No records</td>
|
|
@@ -412,6 +432,7 @@ export default {
|
|
|
412
432
|
'min-width': render ? `${resizeInfo.rendererMinWidth}px;` : `${resizeInfo.minWidth}px`,
|
|
413
433
|
};
|
|
414
434
|
};
|
|
435
|
+
const getSlotName = column => `${column}Node`;
|
|
415
436
|
|
|
416
437
|
return {
|
|
417
438
|
...toRefs(styleInfo),
|
|
@@ -449,6 +470,7 @@ export default {
|
|
|
449
470
|
isHeaderCheckbox,
|
|
450
471
|
getColumnClass,
|
|
451
472
|
getColumnStyle,
|
|
473
|
+
getSlotName,
|
|
452
474
|
bodyStyle,
|
|
453
475
|
};
|
|
454
476
|
},
|
|
@@ -75,7 +75,16 @@
|
|
|
75
75
|
<i></i>
|
|
76
76
|
</span>
|
|
77
77
|
</span>
|
|
78
|
-
|
|
78
|
+
<!-- cell renderer -->
|
|
79
|
+
<template v-if="!!$slots[column.field + 'Node']">
|
|
80
|
+
<slot
|
|
81
|
+
:name="column.field + 'Node'"
|
|
82
|
+
:item="{
|
|
83
|
+
data: node.data,
|
|
84
|
+
}"
|
|
85
|
+
>
|
|
86
|
+
</slot>
|
|
87
|
+
</template>
|
|
79
88
|
</div>
|
|
80
89
|
</td>
|
|
81
90
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="description
|
|
2
|
+
<div class="description tree-grid-toolbar">
|
|
3
3
|
<slot name="toolbarWrapper"></slot>
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
@@ -12,15 +12,15 @@ export default {
|
|
|
12
12
|
|
|
13
13
|
<style lang="scss">
|
|
14
14
|
@import '../../style/index.scss';
|
|
15
|
-
.
|
|
15
|
+
.tree-grid-toolbar {
|
|
16
16
|
margin-bottom: 10px;
|
|
17
17
|
overflow: hidden;
|
|
18
18
|
}
|
|
19
|
-
.
|
|
19
|
+
.tree-grid-toolbar > .search {
|
|
20
20
|
float: right;
|
|
21
21
|
margin-right: 0;
|
|
22
22
|
}
|
|
23
|
-
.
|
|
23
|
+
.tree-grid-toolbar > .ev-button {
|
|
24
24
|
margin: 0 2px 0 2px;
|
|
25
25
|
}
|
|
26
26
|
</style>
|