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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ref, reactive, computed,
|
|
2
|
+
ref, reactive, computed, getCurrentInstance, unref, onBeforeMount, watch,
|
|
3
3
|
} from 'vue';
|
|
4
4
|
import { throttle } from 'lodash-es';
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ const HOUR_CNT = 24;
|
|
|
10
10
|
const MIN_CNT = 60;
|
|
11
11
|
const SEC_CNT = 60;
|
|
12
12
|
const CELL_CNT_IN_ONE_PAGE = 12;
|
|
13
|
-
const CELL_CNT_IN_ONE_ROW =
|
|
13
|
+
const CELL_CNT_IN_ONE_ROW = 4;
|
|
14
14
|
const MONTH_NAME_LIST = {
|
|
15
15
|
fullName: ['January', 'February', 'March', 'April', 'May', 'June',
|
|
16
16
|
'July', 'August', 'September', 'October', 'November', 'December'],
|
|
@@ -27,6 +27,7 @@ const DAY_OF_THE_WEEK_NAME_LIST = {
|
|
|
27
27
|
abbrPascalName: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
|
28
28
|
abbrKorName: ['일', '월', '화', '수', '목', '금', '토'],
|
|
29
29
|
};
|
|
30
|
+
|
|
30
31
|
const ONE_DAY_MS = 86400000;
|
|
31
32
|
const dateReg = new RegExp(/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/);
|
|
32
33
|
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]/);
|
|
@@ -52,7 +53,7 @@ const getSideDateStr = (arr, sideDirection) => {
|
|
|
52
53
|
* @param num
|
|
53
54
|
* @returns {string|*}
|
|
54
55
|
*/
|
|
55
|
-
const lpadToTwoDigits = (num) => {
|
|
56
|
+
export const lpadToTwoDigits = (num) => {
|
|
56
57
|
if (num === null) {
|
|
57
58
|
return '00';
|
|
58
59
|
} else if (+num < 10) {
|
|
@@ -154,7 +155,6 @@ const getDateTimeInfoByType = (param, typeToImport) => {
|
|
|
154
155
|
if (typeToImport === 'sec') return result.sec;
|
|
155
156
|
return result;
|
|
156
157
|
};
|
|
157
|
-
|
|
158
158
|
/**
|
|
159
159
|
* 이전달, 다음달의 달력 상 연도, 월 정보 구하기
|
|
160
160
|
* @param prevNext - 이전, 다음 여부 ('prev'|'next')
|
|
@@ -175,35 +175,101 @@ const getSideMonthCalendarInfo = (prevNext, year, month) => {
|
|
|
175
175
|
};
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
+
/**
|
|
179
|
+
* timeFormat을 체크하여 timeFormat이 있으면 format에 맞는 형식으로 반환
|
|
180
|
+
* @param timeFormat -- props.option?.timeFormat
|
|
181
|
+
* @param dateTimeValue
|
|
182
|
+
* @param typeToImport
|
|
183
|
+
* @returns {Object|number}
|
|
184
|
+
*/
|
|
185
|
+
const getTimeInfoByTimeFormat = (timeFormat, dateTimeValue, typeToImport) => {
|
|
186
|
+
const value = getDateTimeInfoByType(dateTimeValue, typeToImport);
|
|
187
|
+
if (timeFormat) {
|
|
188
|
+
const hour = timeFormat?.split(':')[0];
|
|
189
|
+
const min = timeFormat?.split(':')[1];
|
|
190
|
+
const sec = timeFormat?.split(':')[2];
|
|
191
|
+
if (typeToImport === 'hour') {
|
|
192
|
+
return hour === 'HH' ? value : +hour;
|
|
193
|
+
} else if (typeToImport === 'min') {
|
|
194
|
+
return min === 'mm' ? value : +min;
|
|
195
|
+
} else if (typeToImport === 'sec') {
|
|
196
|
+
return sec === 'ss' ? value : +sec;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return value;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 초기 timeFormat에 따른 modelValue update 함수
|
|
204
|
+
* @param timeFormat - props.options.timeFormat
|
|
205
|
+
* @param modelValue
|
|
206
|
+
* @returns string
|
|
207
|
+
*/
|
|
208
|
+
export const getChangedValueByTimeFormat = (timeFormat, modelValue) => {
|
|
209
|
+
const hourByTimeFormat = lpadToTwoDigits(getTimeInfoByTimeFormat(timeFormat, modelValue, 'hour'));
|
|
210
|
+
const minByTimeFormat = lpadToTwoDigits(getTimeInfoByTimeFormat(timeFormat, modelValue, 'min'));
|
|
211
|
+
const secByTimeFormat = lpadToTwoDigits(getTimeInfoByTimeFormat(timeFormat, modelValue, 'sec'));
|
|
212
|
+
|
|
213
|
+
return `${modelValue.split(' ')[0]} ${hourByTimeFormat}:${minByTimeFormat}:${secByTimeFormat}`;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const compareFromAndToDate = (calendarType, targetDate, modelValue) => {
|
|
217
|
+
if (!modelValue.length) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
const fromDate = calendarType === 'main' ? targetDate : modelValue[0];
|
|
221
|
+
const toDate = calendarType === 'expanded' ? targetDate : modelValue[1];
|
|
222
|
+
|
|
223
|
+
return +new Date(fromDate) > +new Date(toDate);
|
|
224
|
+
};
|
|
225
|
+
|
|
178
226
|
/**
|
|
179
227
|
* date string 값의 MS 값 구하기
|
|
180
228
|
* @param dateStr
|
|
181
229
|
* @returns {number}
|
|
182
230
|
*/
|
|
183
|
-
const getDateMs = dateStr => new Date(`${dateStr}
|
|
231
|
+
const getDateMs = dateStr => new Date(`${dateStr}`).getTime();
|
|
184
232
|
|
|
185
233
|
export const useModel = () => {
|
|
186
234
|
const { props } = getCurrentInstance();
|
|
235
|
+
const timeFormat = props.options?.timeFormat;
|
|
187
236
|
|
|
188
|
-
|
|
237
|
+
/**
|
|
189
238
|
* 현재 선택된 값, 배열인 경우 반응형을 끊기위해 rest 사용
|
|
239
|
+
* selectValue ref로 변환하기 전 modelValue timeFormat에 따라 fetch
|
|
190
240
|
* 1) props.mode: 'date' or 'dateTime' > String
|
|
191
241
|
* 2) props.mode: 'dateMulti' or 'dateRange' > [...Array]
|
|
192
242
|
*/
|
|
193
243
|
let selectedValue;
|
|
194
|
-
if (props.mode !== 'dateMulti' && props.mode !== 'dateRange') {
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|| (props.modelValue.length === 19 && dateTimeReg.exec(props.modelValue))
|
|
244
|
+
if (props.mode !== 'dateMulti' && props.mode !== 'dateRange' && props.mode !== 'dateTimeRange') {
|
|
245
|
+
if (props.modelValue
|
|
246
|
+
&& ((props.modelValue.length === 10 && dateReg.exec(props.modelValue?.toString()))
|
|
247
|
+
|| (props.modelValue.length === 19 && dateTimeReg.exec(props.modelValue?.toString())))
|
|
198
248
|
) {
|
|
199
|
-
|
|
249
|
+
if (props.mode === 'dateTime' && timeFormat) {
|
|
250
|
+
const modelValue = getChangedValueByTimeFormat(timeFormat, props.modelValue);
|
|
251
|
+
selectedValue = ref(modelValue);
|
|
252
|
+
} else {
|
|
253
|
+
selectedValue = ref(props.modelValue);
|
|
254
|
+
}
|
|
200
255
|
} else {
|
|
201
256
|
selectedValue = ref('');
|
|
202
257
|
}
|
|
203
258
|
} else if (Array.isArray(props.modelValue)
|
|
204
|
-
&& props.modelValue.every(v => (
|
|
259
|
+
&& props.modelValue.every(v => (
|
|
260
|
+
!v
|
|
261
|
+
|| (v.length === 10 && dateReg.exec(v))
|
|
262
|
+
|| (v.length === 19 && dateTimeReg.exec(v))
|
|
263
|
+
))
|
|
205
264
|
) {
|
|
206
|
-
|
|
265
|
+
if (props.mode === 'dateTimeRange' && props.modelValue.length === 2 && timeFormat) {
|
|
266
|
+
const modelValue = [];
|
|
267
|
+
modelValue.push(getChangedValueByTimeFormat(timeFormat[0], props.modelValue[0]));
|
|
268
|
+
modelValue.push(getChangedValueByTimeFormat(timeFormat[1], props.modelValue[1]));
|
|
269
|
+
selectedValue = ref([...modelValue]);
|
|
270
|
+
} else {
|
|
271
|
+
selectedValue = ref([...props.modelValue]);
|
|
272
|
+
}
|
|
207
273
|
} else {
|
|
208
274
|
selectedValue = ref([]);
|
|
209
275
|
}
|
|
@@ -223,6 +289,14 @@ export const useModel = () => {
|
|
|
223
289
|
console.warn('[EVUI][Calendar] When mode is \'dateRange\', v-model must be \'Array\' type.');
|
|
224
290
|
} else if (props.modelValue.length !== 0 && props.modelValue.length !== 2) {
|
|
225
291
|
console.warn('[EVUI][Calendar] When mode is \'dateRange\', v-model\'s length is 0 or 2.');
|
|
292
|
+
} else if (getDateMs(`${props.modelValue[0]} 00:00:00`) > getDateMs(`${props.modelValue[1]} 00:00:00`)) {
|
|
293
|
+
console.warn('[EVUI][Calendar] When mode is \'dateRange\', fromDate must be less than toDate.');
|
|
294
|
+
}
|
|
295
|
+
} else if (props.mode === 'dateTimeRange' && props.modelValue) {
|
|
296
|
+
if (!Array.isArray(props.modelValue)) {
|
|
297
|
+
console.warn('[EVUI][Calendar] When mode is \'dateTimeRange\', v-model must be \'Array\' type.');
|
|
298
|
+
} else if (props.modelValue.length !== 0 && props.modelValue.length !== 2) {
|
|
299
|
+
console.warn('[EVUI][Calendar] When mode is \'dateRange\', v-model\'s length is 0 or 2.');
|
|
226
300
|
} else if (getDateMs(props.modelValue[0]) > getDateMs(props.modelValue[1])) {
|
|
227
301
|
console.warn('[EVUI][Calendar] When mode is \'dateRange\', fromDate must be less than toDate.');
|
|
228
302
|
}
|
|
@@ -231,18 +305,14 @@ export const useModel = () => {
|
|
|
231
305
|
|
|
232
306
|
// 메인(좌측) 달력(연, 월, 시, 분, 초) 페이징 정보
|
|
233
307
|
let mainCalendarPageInfo;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
year: getDateTimeInfoByType(selectedValue.value, 'year') || new Date().getFullYear(),
|
|
237
|
-
month: getDateTimeInfoByType(selectedValue.value, 'month') || new Date().getMonth() + 1,
|
|
238
|
-
hour: Math.floor(getDateTimeInfoByType(selectedValue.value, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
239
|
-
min: Math.floor(getDateTimeInfoByType(selectedValue.value, 'min') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
240
|
-
sec: Math.floor(getDateTimeInfoByType(selectedValue.value, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
241
|
-
});
|
|
242
|
-
} else if (Array.isArray(selectedValue.value) && selectedValue.value[0]) {
|
|
308
|
+
const mainValue = !['dateRange', 'dateTimeRange'].includes(props.mode) ? selectedValue.value : selectedValue.value[0];
|
|
309
|
+
if (props.mode) {
|
|
243
310
|
mainCalendarPageInfo = reactive({
|
|
244
|
-
year: getDateTimeInfoByType(
|
|
245
|
-
month: getDateTimeInfoByType(
|
|
311
|
+
year: getDateTimeInfoByType(mainValue, 'year') || new Date().getFullYear(),
|
|
312
|
+
month: getDateTimeInfoByType(mainValue, 'month') || new Date().getMonth() + 1,
|
|
313
|
+
hour: Math.floor(getDateTimeInfoByType(mainValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
314
|
+
min: Math.floor(getDateTimeInfoByType(mainValue, 'min') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
315
|
+
sec: Math.floor(getDateTimeInfoByType(mainValue, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1 || 1,
|
|
246
316
|
});
|
|
247
317
|
} else {
|
|
248
318
|
mainCalendarPageInfo = reactive({
|
|
@@ -251,52 +321,68 @@ export const useModel = () => {
|
|
|
251
321
|
});
|
|
252
322
|
}
|
|
253
323
|
|
|
254
|
-
// 'mode: dateRange'인 경우 확장된 달력(연, 월) 페이징 정보
|
|
324
|
+
// 'mode: dateRange || dateTimeRange', 인 경우 확장된 달력(연, 월) 페이징 정보
|
|
255
325
|
let expandedCalendarPageInfo;
|
|
256
|
-
if (props.mode
|
|
326
|
+
if ((['dateRange', 'dateTimeRange'].includes(props.mode))
|
|
257
327
|
&& Array.isArray(selectedValue.value)
|
|
258
328
|
&& selectedValue.value[1]
|
|
259
329
|
) {
|
|
330
|
+
const expandedValue = selectedValue.value[1];
|
|
260
331
|
const fromDate = {
|
|
261
332
|
year: getDateTimeInfoByType(selectedValue.value[0], 'year'),
|
|
262
333
|
month: getDateTimeInfoByType(selectedValue.value[0], 'month'),
|
|
263
334
|
};
|
|
264
335
|
const toDate = {
|
|
265
|
-
year: getDateTimeInfoByType(
|
|
266
|
-
month: getDateTimeInfoByType(
|
|
336
|
+
year: getDateTimeInfoByType(expandedValue, 'year'),
|
|
337
|
+
month: getDateTimeInfoByType(expandedValue, 'month'),
|
|
267
338
|
};
|
|
268
339
|
// fromDate, toDate의 연, 월이 같은 경우의 확장된 달력 페이징 정보는 다음달로 세팅
|
|
269
|
-
if (fromDate.year === toDate.year && fromDate.month === toDate.month) {
|
|
340
|
+
if (props.mode === 'dateRange' && (fromDate.year === toDate.year && fromDate.month === toDate.month)) {
|
|
270
341
|
expandedCalendarPageInfo = reactive(getSideMonthCalendarInfo(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
342
|
+
'next',
|
|
343
|
+
mainCalendarPageInfo.year,
|
|
344
|
+
mainCalendarPageInfo.month,
|
|
274
345
|
));
|
|
275
346
|
} else {
|
|
276
347
|
expandedCalendarPageInfo = reactive(toDate);
|
|
277
348
|
}
|
|
349
|
+
|
|
350
|
+
if (props.mode === 'dateTimeRange') {
|
|
351
|
+
expandedCalendarPageInfo.hour = Math.floor(getDateTimeInfoByType(expandedValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1 || 1;
|
|
352
|
+
expandedCalendarPageInfo.min = Math.floor(getDateTimeInfoByType(expandedValue, 'min') / CELL_CNT_IN_ONE_PAGE) + 1 || 1;
|
|
353
|
+
expandedCalendarPageInfo.sec = Math.floor(getDateTimeInfoByType(expandedValue, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1 || 1;
|
|
354
|
+
}
|
|
278
355
|
} else {
|
|
279
356
|
expandedCalendarPageInfo = reactive(getSideMonthCalendarInfo(
|
|
280
357
|
'next',
|
|
281
358
|
mainCalendarPageInfo.year,
|
|
282
359
|
mainCalendarPageInfo.month,
|
|
283
360
|
));
|
|
361
|
+
|
|
362
|
+
if (props.mode === 'dateTimeRange') {
|
|
363
|
+
expandedCalendarPageInfo.hour = 1;
|
|
364
|
+
expandedCalendarPageInfo.min = 1;
|
|
365
|
+
expandedCalendarPageInfo.sec = 1;
|
|
366
|
+
}
|
|
284
367
|
}
|
|
285
368
|
|
|
286
369
|
// 현재 달력이 표현되는 월
|
|
287
370
|
const mainCalendarMonth = computed(() =>
|
|
288
|
-
|
|
371
|
+
MONTH_NAME_LIST[props.monthNotation][mainCalendarPageInfo.month - 1]);
|
|
289
372
|
// 다음페이지 달력이 표현되는 월
|
|
290
373
|
const expandedCalendarMonth = computed(() =>
|
|
291
|
-
|
|
374
|
+
MONTH_NAME_LIST[props.monthNotation][expandedCalendarPageInfo.month - 1]);
|
|
292
375
|
// 현재 달력에 표현되는 타입별 요일
|
|
293
376
|
const dayOfTheWeekList = computed(() =>
|
|
294
377
|
DAY_OF_THE_WEEK_NAME_LIST[props.dayOfTheWeekNotation]);
|
|
295
378
|
// mode: dateRange에 두 달력이 연속적인 경우
|
|
296
379
|
const isContinuousMonths = computed(
|
|
297
|
-
() => props.mode === 'dateRange'
|
|
380
|
+
() => (props.mode === 'dateRange'
|
|
298
381
|
&& (getSideMonthCalendarInfo('next', mainCalendarPageInfo.year, mainCalendarPageInfo.month).year === expandedCalendarPageInfo.year
|
|
299
|
-
&& getSideMonthCalendarInfo('next', mainCalendarPageInfo.year, mainCalendarPageInfo.month).month === expandedCalendarPageInfo.month))
|
|
382
|
+
&& getSideMonthCalendarInfo('next', mainCalendarPageInfo.year, mainCalendarPageInfo.month).month === expandedCalendarPageInfo.month))
|
|
383
|
+
|| (props.mode === 'dateTimeRange' && (mainCalendarPageInfo.year === expandedCalendarPageInfo.year
|
|
384
|
+
&& mainCalendarPageInfo.month === expandedCalendarPageInfo.month)),
|
|
385
|
+
);
|
|
300
386
|
|
|
301
387
|
onBeforeMount(() => {
|
|
302
388
|
validateModelValue();
|
|
@@ -322,7 +408,13 @@ export const useCalendarDate = (param) => {
|
|
|
322
408
|
// dateRange 모드의 확장된 달력 테이블의 날짜 정보
|
|
323
409
|
const expandedCalendarTableInfo = reactive(getMatrixArr(CALENDAR_ROWS, CALENDAR_COLS));
|
|
324
410
|
// 시간박스 정보
|
|
325
|
-
const
|
|
411
|
+
const mainTimeTableInfo = reactive({
|
|
412
|
+
hour: [],
|
|
413
|
+
min: [],
|
|
414
|
+
sec: [],
|
|
415
|
+
});
|
|
416
|
+
// dateTimeRange 모드의 확장된 달력 테이블의 시간 박스 정보
|
|
417
|
+
const expandedTimeTableInfo = reactive({
|
|
326
418
|
hour: [],
|
|
327
419
|
min: [],
|
|
328
420
|
sec: [],
|
|
@@ -350,7 +442,7 @@ export const useCalendarDate = (param) => {
|
|
|
350
442
|
((calendarPageInfo.month + 1) % MONTH_CNT) || MONTH_CNT);
|
|
351
443
|
const YEAR_OF_PREV_MONTH = computed(() => (calendarPageInfo.month === 1
|
|
352
444
|
? calendarPageInfo.year - 1 : calendarPageInfo.year));
|
|
353
|
-
const YEAR_OF_NEXT_MONTH = computed(() => (
|
|
445
|
+
const YEAR_OF_NEXT_MONTH = computed(() => (calendarPageInfo.month === 12
|
|
354
446
|
? calendarPageInfo.year + 1 : calendarPageInfo.year));
|
|
355
447
|
// 이번달 1일의 요일
|
|
356
448
|
const dayOfWeekOnThe1stOfThisMonth = computed(() => getDayOfWeekOnThe1stOfMonth(
|
|
@@ -378,10 +470,12 @@ export const useCalendarDate = (param) => {
|
|
|
378
470
|
const setDateInfo = (monthType, i, j) => {
|
|
379
471
|
currDate = formatDateTime({ year, month, date });
|
|
380
472
|
const isDisabled = disabledDate ? disabledDate(new Date(currDate)) : false;
|
|
473
|
+
const isInvalidDate = props.mode === 'dateTimeRange'
|
|
474
|
+
&& compareFromAndToDate(calendarType, `${currDate} 00:00:00`, selectedValue.value);
|
|
381
475
|
const inRangeCls = () => {
|
|
382
|
-
if (props.mode
|
|
383
|
-
if (getDateMs(selectedValue.value[0]) <= getDateMs(currDate)
|
|
384
|
-
&& getDateMs(currDate) <= getDateMs(selectedValue.value[1])
|
|
476
|
+
if (['dateRange'].includes(props.mode) && selectedValue.value.length === 2) {
|
|
477
|
+
if (getDateMs(selectedValue.value[0].split(' ')[0]) <= getDateMs(currDate)
|
|
478
|
+
&& getDateMs(currDate) <= getDateMs(selectedValue.value[1].split(' ')[0])
|
|
385
479
|
) {
|
|
386
480
|
if (getDateMs(selectedValue.value[0]) === getDateMs(selectedValue.value[1])) {
|
|
387
481
|
return ' in-range start-end-date';
|
|
@@ -396,13 +490,21 @@ export const useCalendarDate = (param) => {
|
|
|
396
490
|
}
|
|
397
491
|
return '';
|
|
398
492
|
};
|
|
493
|
+
|
|
494
|
+
const isDateRangeSelected = props.mode === 'dateRange'
|
|
495
|
+
&& selectedValue.value?.map(v => v.split(' ')[0]).includes(currDate);
|
|
496
|
+
// mode:dateTimeRange인 경우는 한 달력에 from, to 선택 못함
|
|
497
|
+
const index = calendarType !== 'main' | 0;
|
|
498
|
+
const isDateTimeRangeSelected = props.mode === 'dateTimeRange'
|
|
499
|
+
&& selectedValue.value.length > index && selectedValue.value[index].split(' ')[0].includes(currDate);
|
|
500
|
+
|
|
399
501
|
// mode가 dateRange일 때는 이전, 다음달에 selected 를 하지 않는다.
|
|
400
502
|
calendarTableInfo[i][j] = {
|
|
401
|
-
monthType: `${monthType}${isDisabled ? ' disabled' : ''}${inRangeCls()}`,
|
|
503
|
+
monthType: `${monthType}${isDisabled || isInvalidDate ? ' disabled' : ''}${inRangeCls()}`,
|
|
402
504
|
isToday: TODAY_YMD === currDate,
|
|
403
|
-
isSelected: props.mode
|
|
505
|
+
isSelected: !['dateRange', 'dateTimeRange'].includes(props.mode)
|
|
404
506
|
? selectedValue.value?.includes(currDate)
|
|
405
|
-
: monthType === '' &&
|
|
507
|
+
: monthType === '' && (isDateRangeSelected || isDateTimeRangeSelected),
|
|
406
508
|
year,
|
|
407
509
|
month,
|
|
408
510
|
date,
|
|
@@ -455,6 +557,35 @@ export const useCalendarDate = (param) => {
|
|
|
455
557
|
* Calendar 시간 정보 세팅하기
|
|
456
558
|
*/
|
|
457
559
|
const setHmsTime = () => {
|
|
560
|
+
const timeFormat = props.options?.timeFormat;
|
|
561
|
+
const mainTimeFormat = Array.isArray(timeFormat) ? timeFormat[0] : timeFormat;
|
|
562
|
+
const expandedTimeFormat = Array.isArray(timeFormat) ? timeFormat[1] : '';
|
|
563
|
+
const mainDateTimeValue = props.mode === 'dateTimeRange' ? selectedValue.value[0] : selectedValue.value;
|
|
564
|
+
const expandedDateTimeValue = props.mode === 'dateTimeRange' ? selectedValue.value[1] : '';
|
|
565
|
+
|
|
566
|
+
const compareDateTimeValue = (calendarType, timeType, value) => {
|
|
567
|
+
const dateTimeValue = calendarType === 'main' ? mainDateTimeValue : expandedDateTimeValue;
|
|
568
|
+
if (!dateTimeValue) {
|
|
569
|
+
return false;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const date = dateTimeValue.split(' ')[0];
|
|
573
|
+
let hour = getDateTimeInfoByType(dateTimeValue, 'hour');
|
|
574
|
+
let min = getDateTimeInfoByType(dateTimeValue, 'min');
|
|
575
|
+
let sec = getDateTimeInfoByType(dateTimeValue, 'sec');
|
|
576
|
+
|
|
577
|
+
if (timeType === 'hour') {
|
|
578
|
+
hour = value;
|
|
579
|
+
} else if (timeType === 'min') {
|
|
580
|
+
min = value;
|
|
581
|
+
} else if (timeType === 'sec') {
|
|
582
|
+
sec = value;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const targetDateTimeValue = `${date} ${lpadToTwoDigits(hour)}:${lpadToTwoDigits(min)}:${lpadToTwoDigits(sec)}`;
|
|
586
|
+
return compareFromAndToDate(calendarType, targetDateTimeValue, selectedValue.value);
|
|
587
|
+
};
|
|
588
|
+
|
|
458
589
|
['hour', 'min', 'sec'].forEach((v) => {
|
|
459
590
|
let cnt = SEC_CNT;
|
|
460
591
|
if (v === 'hour') {
|
|
@@ -462,13 +593,25 @@ export const useCalendarDate = (param) => {
|
|
|
462
593
|
} else if (v === 'min') {
|
|
463
594
|
cnt = MIN_CNT;
|
|
464
595
|
}
|
|
596
|
+
const mainTimeValue = mainDateTimeValue && mainDateTimeValue.length > 0
|
|
597
|
+
? getTimeInfoByTimeFormat(mainTimeFormat, mainDateTimeValue, v) : -1;
|
|
598
|
+
const expandedTimeValue = expandedDateTimeValue && expandedDateTimeValue.length > 0
|
|
599
|
+
? getTimeInfoByTimeFormat(expandedTimeFormat, expandedDateTimeValue, v) : -1;
|
|
465
600
|
for (let i = 0; i < cnt; i++) {
|
|
466
|
-
|
|
601
|
+
mainTimeTableInfo[v][i] = {
|
|
467
602
|
timeType: v,
|
|
468
603
|
num: i,
|
|
469
|
-
isSelected:
|
|
470
|
-
|
|
604
|
+
isSelected: mainTimeValue === i,
|
|
605
|
+
isDisabled: props.mode === 'dateTimeRange' && compareDateTimeValue('main', v, i),
|
|
471
606
|
};
|
|
607
|
+
if (props.mode === 'dateTimeRange') {
|
|
608
|
+
expandedTimeTableInfo[v][i] = {
|
|
609
|
+
timeType: v,
|
|
610
|
+
num: i,
|
|
611
|
+
isSelected: expandedTimeValue === i,
|
|
612
|
+
isDisabled: compareDateTimeValue('expanded', v, i),
|
|
613
|
+
};
|
|
614
|
+
}
|
|
472
615
|
}
|
|
473
616
|
});
|
|
474
617
|
};
|
|
@@ -478,37 +621,25 @@ export const useCalendarDate = (param) => {
|
|
|
478
621
|
* @param timeType - {'hour'|'min'|'sec'}
|
|
479
622
|
* @param i - rows
|
|
480
623
|
* @param j - cols
|
|
481
|
-
* @
|
|
624
|
+
* @param calendarType - {'main'|'expanded'}
|
|
625
|
+
* @returns {object} - cellInfo
|
|
482
626
|
*/
|
|
483
|
-
const getTimeInfo = (timeType, i, j) => {
|
|
484
|
-
const
|
|
627
|
+
const getTimeInfo = (timeType, i, j, calendarType) => {
|
|
628
|
+
const pageInfo = calendarType === 'main' ? mainCalendarPageInfo : expandedCalendarPageInfo;
|
|
629
|
+
const timeInfo = calendarType === 'main' ? mainTimeTableInfo : expandedTimeTableInfo;
|
|
630
|
+
const currPage = pageInfo[timeType] - 1;
|
|
485
631
|
const currRowIdx = i - 1;
|
|
486
632
|
const currColIdx = j - 1;
|
|
487
633
|
const currIdx = (currPage * CELL_CNT_IN_ONE_PAGE)
|
|
488
634
|
+ (currRowIdx * CELL_CNT_IN_ONE_ROW) + currColIdx;
|
|
489
|
-
return
|
|
635
|
+
return timeInfo[timeType][currIdx];
|
|
490
636
|
};
|
|
491
637
|
|
|
492
|
-
watch(
|
|
493
|
-
() => props.modelValue,
|
|
494
|
-
(curr) => {
|
|
495
|
-
selectedValue.value = curr;
|
|
496
|
-
if (props.mode !== 'dateRange') {
|
|
497
|
-
setCalendarDate('main');
|
|
498
|
-
if (props.mode === 'dateTime') {
|
|
499
|
-
setHmsTime();
|
|
500
|
-
}
|
|
501
|
-
} else {
|
|
502
|
-
setCalendarDate('main');
|
|
503
|
-
setCalendarDate('expanded');
|
|
504
|
-
}
|
|
505
|
-
},
|
|
506
|
-
);
|
|
507
|
-
|
|
508
638
|
return {
|
|
509
639
|
mainCalendarTableInfo,
|
|
510
640
|
expandedCalendarTableInfo,
|
|
511
|
-
|
|
641
|
+
mainTimeTableInfo,
|
|
642
|
+
expandedTimeTableInfo,
|
|
512
643
|
setCalendarDate,
|
|
513
644
|
setHmsTime,
|
|
514
645
|
getTimeInfo,
|
|
@@ -518,6 +649,7 @@ export const useCalendarDate = (param) => {
|
|
|
518
649
|
export const useEvent = (param) => {
|
|
519
650
|
const { props, emit } = getCurrentInstance();
|
|
520
651
|
const disabledDate = props.options.disabledDate;
|
|
652
|
+
const timeFormat = props.options?.timeFormat;
|
|
521
653
|
const {
|
|
522
654
|
selectedValue,
|
|
523
655
|
mainCalendarPageInfo,
|
|
@@ -530,6 +662,21 @@ export const useEvent = (param) => {
|
|
|
530
662
|
const dateRangeClickedDate = ref('');
|
|
531
663
|
// dateRange mode에서 클릭한번 후 커서에 따라 날짜를 마우스오버하는 경우 dynamic argument로 이벤트명 설정
|
|
532
664
|
const calendarEventName = ref(null);
|
|
665
|
+
// dateTime 또는 dateTimeRange에서 timeFormat이 있는 경우 event 막음
|
|
666
|
+
const mainTimeFormat = Array.isArray(timeFormat) ? timeFormat[0] : timeFormat;
|
|
667
|
+
const expandedTimeFormat = Array.isArray(timeFormat) ? timeFormat[1] : '';
|
|
668
|
+
const preventTimeEventType = {
|
|
669
|
+
main: {
|
|
670
|
+
hour: mainTimeFormat && mainTimeFormat.split(':')[0] !== 'HH',
|
|
671
|
+
min: mainTimeFormat && mainTimeFormat.split(':')[1] !== 'mm',
|
|
672
|
+
sec: mainTimeFormat && mainTimeFormat.split(':')[2] !== 'ss',
|
|
673
|
+
},
|
|
674
|
+
expanded: {
|
|
675
|
+
hour: expandedTimeFormat && expandedTimeFormat.split(':')[0] !== 'HH',
|
|
676
|
+
min: expandedTimeFormat && expandedTimeFormat.split(':')[1] !== 'mm',
|
|
677
|
+
sec: expandedTimeFormat && expandedTimeFormat.split(':')[2] !== 'ss',
|
|
678
|
+
},
|
|
679
|
+
};
|
|
533
680
|
|
|
534
681
|
/**
|
|
535
682
|
* 입력받은 dateTime object에 calendar date, time 영역 페이지 세팅
|
|
@@ -547,16 +694,34 @@ export const useEvent = (param) => {
|
|
|
547
694
|
calendarPageInfo.month = month;
|
|
548
695
|
}
|
|
549
696
|
if (hour) {
|
|
550
|
-
|
|
697
|
+
calendarPageInfo.hour = hour;
|
|
551
698
|
}
|
|
552
699
|
if (min) {
|
|
553
|
-
|
|
700
|
+
calendarPageInfo.min = min;
|
|
554
701
|
}
|
|
555
702
|
if (sec) {
|
|
556
|
-
|
|
703
|
+
calendarPageInfo.sec = sec;
|
|
557
704
|
}
|
|
558
705
|
};
|
|
559
706
|
|
|
707
|
+
/**
|
|
708
|
+
* page를 Array로 담아 페이지 세팅
|
|
709
|
+
* @param pageList
|
|
710
|
+
*/
|
|
711
|
+
const updatePageList = (pageList) => {
|
|
712
|
+
pageList?.forEach((currValue, index) => {
|
|
713
|
+
const changeCalendarType = index === 0 ? 'main' : 'expanded';
|
|
714
|
+
setCalendarPageInfo(changeCalendarType, {
|
|
715
|
+
year: getDateTimeInfoByType(currValue, 'year'),
|
|
716
|
+
month: getDateTimeInfoByType(currValue, 'month'),
|
|
717
|
+
hour: Math.floor(getDateTimeInfoByType(currValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
718
|
+
min: Math.floor(getDateTimeInfoByType(currValue, 'min') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
719
|
+
sec: Math.floor(getDateTimeInfoByType(currValue, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
720
|
+
});
|
|
721
|
+
setCalendarDate(changeCalendarType);
|
|
722
|
+
});
|
|
723
|
+
};
|
|
724
|
+
|
|
560
725
|
/**
|
|
561
726
|
* Calendar 의 Month 이동시키기 (이전, 이후)
|
|
562
727
|
* expandedCalendar가 존재하는 경우(mode: timeRange)
|
|
@@ -566,7 +731,7 @@ export const useEvent = (param) => {
|
|
|
566
731
|
* @param type - {'prev'|'next'}
|
|
567
732
|
*/
|
|
568
733
|
const moveMonth = (calendarType, type) => {
|
|
569
|
-
const isDateRangeMode = props.mode
|
|
734
|
+
const isDateRangeMode = ['dateRange', 'dateTimeRange'].includes(props.mode);
|
|
570
735
|
let calendarPageInfo = mainCalendarPageInfo;
|
|
571
736
|
if (!isDateRangeMode) {
|
|
572
737
|
if (type === 'prev') {
|
|
@@ -591,11 +756,12 @@ export const useEvent = (param) => {
|
|
|
591
756
|
mainCalendarPageInfo.year,
|
|
592
757
|
mainCalendarPageInfo.month,
|
|
593
758
|
);
|
|
759
|
+
const targetYearMonth = props.mode === 'dateRange' ? nextYearMonth : mainCalendarPageInfo;
|
|
594
760
|
// 두 달력간의 연속 여부 (메인 달력 + 1Month === 확장된 달력)
|
|
595
761
|
// 연속된 경우 mainCalendar와 expandedCalendar는 서로 같은 달로 이동 불가
|
|
596
762
|
// mainCalendar Month < expandedCalendar Month
|
|
597
|
-
const isContinuousMonths = expandedCalendarPageInfo.year ===
|
|
598
|
-
&& expandedCalendarPageInfo.month ===
|
|
763
|
+
const isContinuousMonths = expandedCalendarPageInfo.year === targetYearMonth.year
|
|
764
|
+
&& expandedCalendarPageInfo.month === targetYearMonth.month;
|
|
599
765
|
if (type === 'prev') {
|
|
600
766
|
if (isContinuousMonths && calendarType === 'expanded') {
|
|
601
767
|
return;
|
|
@@ -632,12 +798,16 @@ export const useEvent = (param) => {
|
|
|
632
798
|
|
|
633
799
|
/**
|
|
634
800
|
* Calendar Date 일자 클릭 이벤트
|
|
801
|
+
* @param calendarType - {main|expanded}
|
|
635
802
|
* @param dateInfo
|
|
636
803
|
*/
|
|
637
804
|
const clickDate = (calendarType, dateInfo) => {
|
|
638
805
|
const { year, month, date, monthType } = dateInfo;
|
|
639
806
|
const CURR_DATE_STR = formatDateTime({ year, month, date });
|
|
640
|
-
const isExistCurrDate = props.modelValue
|
|
807
|
+
const isExistCurrDate = props.modelValue ? (Array.isArray(props.modelValue)
|
|
808
|
+
? props.modelValue?.map(v => v.split(' ')[0])
|
|
809
|
+
: props.modelValue.split(' ')[0])
|
|
810
|
+
.includes(CURR_DATE_STR) : false;
|
|
641
811
|
// 제한된 날짜는 선택할 수 없다.
|
|
642
812
|
if (disabledDate && disabledDate(new Date(CURR_DATE_STR)) && !isExistCurrDate) {
|
|
643
813
|
return;
|
|
@@ -671,13 +841,21 @@ export const useEvent = (param) => {
|
|
|
671
841
|
case 'dateTime': {
|
|
672
842
|
const isExistTime = !!(selectedValue.value?.split(' ')[1]);
|
|
673
843
|
const CURR_TIME_HMS = isExistTime
|
|
674
|
-
|
|
675
|
-
selectedValue.value =
|
|
844
|
+
? selectedValue.value?.split(' ')[1] : '00:00:00';
|
|
845
|
+
selectedValue.value = getChangedValueByTimeFormat(
|
|
846
|
+
timeFormat,
|
|
847
|
+
`${CURR_DATE_STR} ${CURR_TIME_HMS}`,
|
|
848
|
+
);
|
|
676
849
|
moveDispCalendarMonth();
|
|
677
|
-
emit('update:modelValue',
|
|
850
|
+
emit('update:modelValue', selectedValue.value);
|
|
678
851
|
setCalendarDate('main');
|
|
679
852
|
if (!isExistTime) {
|
|
680
|
-
|
|
853
|
+
const currTime = selectedValue.value.split(' ')[1].split(':');
|
|
854
|
+
setCalendarPageInfo('main', {
|
|
855
|
+
hour: Math.floor(currTime[0] / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
856
|
+
min: Math.floor(currTime[1] / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
857
|
+
sec: Math.floor(currTime[2] / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
858
|
+
});
|
|
681
859
|
setHmsTime();
|
|
682
860
|
}
|
|
683
861
|
break;
|
|
@@ -747,6 +925,61 @@ export const useEvent = (param) => {
|
|
|
747
925
|
}
|
|
748
926
|
break;
|
|
749
927
|
}
|
|
928
|
+
case 'dateTimeRange': {
|
|
929
|
+
const currIndex = calendarType !== 'main' | 0;
|
|
930
|
+
if (!selectedValue.value.length) {
|
|
931
|
+
let fromDate = `${CURR_DATE_STR} 00:00:00`;
|
|
932
|
+
let toDate = `${CURR_DATE_STR} 00:00:00`;
|
|
933
|
+
if (timeFormat && timeFormat.length) {
|
|
934
|
+
fromDate = getChangedValueByTimeFormat(
|
|
935
|
+
timeFormat[0],
|
|
936
|
+
fromDate,
|
|
937
|
+
);
|
|
938
|
+
toDate = getChangedValueByTimeFormat(
|
|
939
|
+
timeFormat[1],
|
|
940
|
+
toDate,
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
selectedValue.value.push(fromDate);
|
|
944
|
+
selectedValue.value.push(toDate);
|
|
945
|
+
|
|
946
|
+
selectedValue.value?.forEach((currValue, index) => {
|
|
947
|
+
setCalendarPageInfo(index === 0 ? 'main' : 'expanded', {
|
|
948
|
+
year: getDateTimeInfoByType(currValue, 'year'),
|
|
949
|
+
month: getDateTimeInfoByType(currValue, 'month'),
|
|
950
|
+
hour: Math.floor(getDateTimeInfoByType(currValue, 'hour') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
951
|
+
min: Math.floor(getDateTimeInfoByType(currValue, 'min') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
952
|
+
sec: Math.floor(getDateTimeInfoByType(currValue, 'sec') / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
setCalendarDate('main');
|
|
956
|
+
setCalendarDate('expanded');
|
|
957
|
+
setHmsTime();
|
|
958
|
+
} else {
|
|
959
|
+
const CURR_TIME_HMS = selectedValue.value[currIndex]?.split(' ')[1] || '00:00:00';
|
|
960
|
+
|
|
961
|
+
let currDate = `${CURR_DATE_STR} ${CURR_TIME_HMS}`;
|
|
962
|
+
if (timeFormat && timeFormat.length) {
|
|
963
|
+
currDate = getChangedValueByTimeFormat(
|
|
964
|
+
timeFormat[currIndex],
|
|
965
|
+
currDate,
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const fromDate = currIndex ? selectedValue.value[0] : currDate;
|
|
970
|
+
const toDate = currIndex ? currDate : selectedValue.value[1];
|
|
971
|
+
|
|
972
|
+
if (new Date(fromDate).getTime() > new Date(toDate).getTime()) {
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
selectedValue.value[currIndex] = currDate;
|
|
977
|
+
moveDispCalendarMonth();
|
|
978
|
+
setCalendarDate(calendarType);
|
|
979
|
+
}
|
|
980
|
+
emit('update:modelValue', [...selectedValue.value]);
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
750
983
|
default:
|
|
751
984
|
break;
|
|
752
985
|
}
|
|
@@ -754,102 +987,155 @@ export const useEvent = (param) => {
|
|
|
754
987
|
|
|
755
988
|
/**
|
|
756
989
|
* Calendar mode: dateTime인 경우 HMS 이동 화살표 클릭 이벤트
|
|
990
|
+
* @param calendarType - {main|expanded}
|
|
757
991
|
* @param timeType - {hour|min|sec}
|
|
758
992
|
* @param arrow - {up|down}
|
|
759
993
|
*/
|
|
760
|
-
const clickHmsBtn = (timeType, arrow) => {
|
|
994
|
+
const clickHmsBtn = (calendarType, timeType, arrow) => {
|
|
995
|
+
if (preventTimeEventType[calendarType][timeType]) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const calendarPageInfo = calendarType === 'expanded'
|
|
1000
|
+
? expandedCalendarPageInfo : mainCalendarPageInfo;
|
|
761
1001
|
const FIRST_PAGE = 1;
|
|
762
1002
|
const HOUR_MAX_PAGE = 2;
|
|
763
1003
|
const MINUTE_MAX_PAGE = 5;
|
|
764
1004
|
const SECOND_MAX_PAGE = 5;
|
|
765
1005
|
if (timeType === 'hour') {
|
|
766
|
-
if (arrow === 'down' &&
|
|
767
|
-
|
|
768
|
-
} else if (arrow === 'up' &&
|
|
769
|
-
|
|
1006
|
+
if (arrow === 'down' && calendarPageInfo.hour < HOUR_MAX_PAGE) {
|
|
1007
|
+
calendarPageInfo.hour++;
|
|
1008
|
+
} else if (arrow === 'up' && calendarPageInfo.hour > FIRST_PAGE) {
|
|
1009
|
+
calendarPageInfo.hour--;
|
|
770
1010
|
}
|
|
771
1011
|
} else if (timeType === 'min') {
|
|
772
|
-
if (arrow === 'down' &&
|
|
773
|
-
|
|
774
|
-
} else if (arrow === 'up' &&
|
|
775
|
-
|
|
1012
|
+
if (arrow === 'down' && calendarPageInfo.min < MINUTE_MAX_PAGE) {
|
|
1013
|
+
calendarPageInfo.min++;
|
|
1014
|
+
} else if (arrow === 'up' && calendarPageInfo.min > FIRST_PAGE) {
|
|
1015
|
+
calendarPageInfo.min--;
|
|
776
1016
|
}
|
|
777
1017
|
} else if (timeType === 'sec') {
|
|
778
|
-
if (arrow === 'down' &&
|
|
779
|
-
|
|
780
|
-
} else if (arrow === 'up' &&
|
|
781
|
-
|
|
1018
|
+
if (arrow === 'down' && calendarPageInfo.sec < SECOND_MAX_PAGE) {
|
|
1019
|
+
calendarPageInfo.sec++;
|
|
1020
|
+
} else if (arrow === 'up' && calendarPageInfo.sec > FIRST_PAGE) {
|
|
1021
|
+
calendarPageInfo.sec--;
|
|
782
1022
|
}
|
|
783
1023
|
}
|
|
784
1024
|
};
|
|
785
1025
|
|
|
786
1026
|
/**
|
|
787
1027
|
* Click cell In HMS area
|
|
1028
|
+
* @param calendarType - {main|expanded}
|
|
788
1029
|
* @param timeType - {hour|min|sec}
|
|
789
1030
|
* @param i - row
|
|
790
1031
|
* @param j - col
|
|
791
1032
|
*/
|
|
792
|
-
const clickTime = (timeType, i, j) => {
|
|
793
|
-
|
|
1033
|
+
const clickTime = (calendarType, timeType, i, j) => {
|
|
1034
|
+
if (preventTimeEventType[calendarType][timeType]) {
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
const calendarPageInfo = calendarType === 'expanded'
|
|
1039
|
+
? expandedCalendarPageInfo : mainCalendarPageInfo;
|
|
1040
|
+
const currPage = calendarPageInfo[timeType] - 1;
|
|
794
1041
|
const currRowIdx = i - 1;
|
|
795
1042
|
const currColIdx = j - 1;
|
|
796
1043
|
const clickedNum = (currPage * CELL_CNT_IN_ONE_PAGE)
|
|
797
1044
|
+ (currRowIdx * CELL_CNT_IN_ONE_ROW) + currColIdx;
|
|
1045
|
+
const TODAY = new Date();
|
|
1046
|
+
const TODAY_INFO = {
|
|
1047
|
+
year: TODAY.getFullYear(),
|
|
1048
|
+
month: TODAY.getMonth() + 1,
|
|
1049
|
+
date: TODAY.getDate(),
|
|
1050
|
+
};
|
|
1051
|
+
let EXIST_MODEL = true;
|
|
1052
|
+
let pageUpdateList = [];
|
|
1053
|
+
|
|
1054
|
+
const getTimeValueByType = () => {
|
|
1055
|
+
let targetTimeValue;
|
|
1056
|
+
if (timeType === 'hour') {
|
|
1057
|
+
targetTimeValue = `${lpadToTwoDigits(clickedNum)}:00:00'`;
|
|
1058
|
+
} else if (timeType === 'min') {
|
|
1059
|
+
targetTimeValue = `00:${lpadToTwoDigits(clickedNum)}:00`;
|
|
1060
|
+
} else if (timeType === 'sec') {
|
|
1061
|
+
targetTimeValue = `00:00:${lpadToTwoDigits(clickedNum)}`;
|
|
1062
|
+
}
|
|
1063
|
+
return `${formatDateTime(TODAY_INFO)} ${targetTimeValue}`;
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
const getChangedValue = (targetValue) => {
|
|
1067
|
+
const HOUR_START_IDX = 11;
|
|
1068
|
+
const MIN_START_IDX = 14;
|
|
1069
|
+
const SEC_START_IDX = 17;
|
|
1070
|
+
const REPLACE_TEXT_SIZE = 2;
|
|
1071
|
+
let START_IDX = HOUR_START_IDX;
|
|
1072
|
+
if (timeType === 'min') {
|
|
1073
|
+
START_IDX = MIN_START_IDX;
|
|
1074
|
+
} else if (timeType === 'sec') {
|
|
1075
|
+
START_IDX = SEC_START_IDX;
|
|
1076
|
+
}
|
|
1077
|
+
return `${targetValue?.substr(0, START_IDX)}${lpadToTwoDigits(clickedNum)}${targetValue?.substr(START_IDX + REPLACE_TEXT_SIZE)}`;
|
|
1078
|
+
};
|
|
798
1079
|
|
|
799
1080
|
if (props.mode === 'dateTime') {
|
|
800
|
-
const EXIST_YMD = !!(props.modelValue?.split(' ')[0]);
|
|
801
|
-
const TODAY = new Date();
|
|
802
|
-
const TODAY_INFO = {
|
|
803
|
-
year: TODAY.getFullYear(),
|
|
804
|
-
month: TODAY.getMonth() + 1,
|
|
805
|
-
date: TODAY.getDate(),
|
|
806
|
-
};
|
|
807
1081
|
if (!props.modelValue) {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1082
|
+
EXIST_MODEL = false;
|
|
1083
|
+
selectedValue.value = getChangedValueByTimeFormat(
|
|
1084
|
+
timeFormat,
|
|
1085
|
+
getTimeValueByType(),
|
|
1086
|
+
);
|
|
1087
|
+
emit('update:modelValue', selectedValue.value);
|
|
1088
|
+
} else {
|
|
1089
|
+
selectedValue.value = getChangedValueByTimeFormat(
|
|
1090
|
+
timeFormat,
|
|
1091
|
+
getChangedValue(props.modelValue),
|
|
1092
|
+
);
|
|
1093
|
+
emit('update:modelValue', selectedValue.value);
|
|
1094
|
+
}
|
|
1095
|
+
pageUpdateList.push(selectedValue.value);
|
|
1096
|
+
} else {
|
|
1097
|
+
const index = calendarType !== 'main' | 0;
|
|
1098
|
+
if (!props.modelValue.length) {
|
|
1099
|
+
const timeValue = getTimeValueByType();
|
|
1100
|
+
selectedValue.value = [timeValue, timeValue];
|
|
1101
|
+
|
|
1102
|
+
if (timeFormat && timeFormat.length) {
|
|
1103
|
+
selectedValue.value = [...selectedValue.value
|
|
1104
|
+
.map((v, idx) => getChangedValueByTimeFormat(timeFormat[idx], v))];
|
|
817
1105
|
}
|
|
1106
|
+
|
|
1107
|
+
EXIST_MODEL = false;
|
|
1108
|
+
pageUpdateList = selectedValue.value;
|
|
818
1109
|
} else {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
START_IDX = MIN_START_IDX;
|
|
826
|
-
} else if (timeType === 'sec') {
|
|
827
|
-
START_IDX = SEC_START_IDX;
|
|
1110
|
+
let currDateTime = getChangedValue(props.modelValue[index]);
|
|
1111
|
+
if (timeFormat && timeFormat.length) {
|
|
1112
|
+
currDateTime = getChangedValueByTimeFormat(
|
|
1113
|
+
timeFormat[index],
|
|
1114
|
+
currDateTime,
|
|
1115
|
+
);
|
|
828
1116
|
}
|
|
829
|
-
selectedValue.value = `${props.modelValue.substr(0, START_IDX)}${lpadToTwoDigits(clickedNum)}${props.modelValue.substr(START_IDX + REPLACE_TEXT_SIZE)}`;
|
|
830
|
-
emit('update:modelValue', `${props.modelValue.substr(0, START_IDX)}${lpadToTwoDigits(clickedNum)}${props.modelValue.substr(START_IDX + REPLACE_TEXT_SIZE)}`);
|
|
831
|
-
}
|
|
832
1117
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
month: TODAY_INFO.month,
|
|
842
|
-
[timeType]: Math.floor(clickedNum / CELL_CNT_IN_ONE_PAGE) + 1,
|
|
843
|
-
},
|
|
844
|
-
});
|
|
845
|
-
setCalendarDate('main');
|
|
1118
|
+
const fromDate = index ? selectedValue.value[0] : currDateTime;
|
|
1119
|
+
const toDate = index ? currDateTime : selectedValue.value[1];
|
|
1120
|
+
|
|
1121
|
+
if (new Date(fromDate).getTime() > new Date(toDate).getTime()) {
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
selectedValue.value[index] = currDateTime;
|
|
846
1126
|
}
|
|
847
|
-
|
|
1127
|
+
emit('update:modelValue', [...selectedValue.value]);
|
|
1128
|
+
}
|
|
1129
|
+
setHmsTime();
|
|
1130
|
+
// dateTime의 v-model값이 없는 경우 time area를 클릭하였을 때 date의 값은 today로 세팅
|
|
1131
|
+
if (!EXIST_MODEL) {
|
|
1132
|
+
updatePageList(pageUpdateList);
|
|
848
1133
|
}
|
|
849
1134
|
};
|
|
850
1135
|
|
|
851
1136
|
/**
|
|
852
1137
|
* Wheel up or wheel down In Calendar Month(tbody) area
|
|
1138
|
+
* @param calendarType - {main|expanded}
|
|
853
1139
|
* @param e
|
|
854
1140
|
*/
|
|
855
1141
|
const wheelMonth = (calendarType, e) => {
|
|
@@ -859,11 +1145,16 @@ export const useEvent = (param) => {
|
|
|
859
1145
|
|
|
860
1146
|
/**
|
|
861
1147
|
* Wheel up or wheel down In Calendar Time(HMS) area
|
|
1148
|
+
* @param calendarType - {main|expanded}
|
|
862
1149
|
* @param timeType - {hour|min|sec}
|
|
863
1150
|
* @param e
|
|
864
1151
|
*/
|
|
865
|
-
const wheelTime = (timeType, e) => {
|
|
866
|
-
|
|
1152
|
+
const wheelTime = (calendarType, timeType, e) => {
|
|
1153
|
+
if (preventTimeEventType[calendarType][timeType]) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
clickHmsBtn(calendarType, timeType, e.deltaY > 0 ? 'down' : 'up');
|
|
867
1158
|
};
|
|
868
1159
|
|
|
869
1160
|
/**
|
|
@@ -912,6 +1203,32 @@ export const useEvent = (param) => {
|
|
|
912
1203
|
}
|
|
913
1204
|
}, 10);
|
|
914
1205
|
|
|
1206
|
+
/**
|
|
1207
|
+
* Calendar Info 전체 업데이트
|
|
1208
|
+
*/
|
|
1209
|
+
const resetCalendarInfo = () => {
|
|
1210
|
+
let pageUpdateList = [];
|
|
1211
|
+
|
|
1212
|
+
if (['date', 'dateTime'].includes(props.mode)) {
|
|
1213
|
+
pageUpdateList.push(selectedValue.value);
|
|
1214
|
+
} else {
|
|
1215
|
+
pageUpdateList = selectedValue.value;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
if (['dateTime', 'dateTimeRange'].includes(props.mode)) {
|
|
1219
|
+
updatePageList(pageUpdateList);
|
|
1220
|
+
setHmsTime();
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1224
|
+
watch(
|
|
1225
|
+
() => props.modelValue,
|
|
1226
|
+
(curr) => {
|
|
1227
|
+
selectedValue.value = curr;
|
|
1228
|
+
resetCalendarInfo();
|
|
1229
|
+
},
|
|
1230
|
+
);
|
|
1231
|
+
|
|
915
1232
|
return {
|
|
916
1233
|
clickPrevNextBtn,
|
|
917
1234
|
clickDate,
|
|
@@ -919,7 +1236,9 @@ export const useEvent = (param) => {
|
|
|
919
1236
|
clickTime,
|
|
920
1237
|
wheelMonth,
|
|
921
1238
|
wheelTime,
|
|
1239
|
+
resetCalendarInfo,
|
|
922
1240
|
calendarEventName,
|
|
923
1241
|
onMousemoveDate,
|
|
1242
|
+
preventTimeEventType,
|
|
924
1243
|
};
|
|
925
1244
|
};
|