renusify 2.5.2 → 3.0.1
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/components/app/index.vue +74 -22
- package/components/app/toast/index.vue +76 -71
- package/components/app/toast/toast.vue +62 -44
- package/components/avatar/index.vue +207 -84
- package/components/button/buttonConfirm.vue +53 -26
- package/components/button/buttonGroup.js +0 -2
- package/components/button/buttonGroup.vue +310 -62
- package/components/button/index.vue +584 -100
- package/components/calendar/index.js +0 -2
- package/components/calendar/index.vue +326 -262
- package/components/calendar/month.vue +64 -55
- package/components/calendar/year.vue +30 -25
- package/components/card/index.vue +139 -59
- package/components/codeEditor/highlightCss.vue +38 -39
- package/components/codeEditor/highlightHtml.vue +64 -64
- package/components/codeEditor/highlightJs.vue +37 -38
- package/components/codeEditor/index.vue +129 -79
- package/components/codeEditor/run.vue +225 -39
- package/components/codeEditor/useCodeFormatter.js +150 -0
- package/components/confirm/index.vue +139 -80
- package/components/container/col.vue +5 -4
- package/components/container/divider.vue +28 -19
- package/components/container/index.vue +34 -15
- package/components/container/row.vue +26 -9
- package/components/container/spacer.vue +2 -4
- package/components/container/style.scss +3 -0
- package/components/content/index.vue +49 -32
- package/components/cropper/index.vue +401 -244
- package/components/float/index.vue +542 -415
- package/components/form/addressInput/index.vue +184 -109
- package/components/form/camInput/index.vue +370 -244
- package/components/form/checkInput/index.vue +138 -71
- package/components/form/checkboxInput/index.vue +93 -49
- package/components/form/colorInput/Alpha.vue +81 -83
- package/components/form/colorInput/Hue.vue +91 -68
- package/components/form/colorInput/Preview.vue +43 -47
- package/components/form/colorInput/Saturation.vue +101 -86
- package/components/form/colorInput/index.vue +71 -39
- package/components/form/colorInput/picker.vue +111 -106
- package/components/form/colorInput/useColor.js +153 -0
- package/components/form/dateInput/index.vue +691 -356
- package/components/form/dateInput/month.vue +63 -54
- package/components/form/dateInput/year.vue +35 -25
- package/components/form/fileInput/index.js +0 -1
- package/components/form/fileInput/index.vue +263 -106
- package/components/form/fileInput/single.vue +332 -168
- package/components/form/groupInput/index.vue +199 -101
- package/components/form/index.vue +189 -83
- package/components/form/input/index.vue +416 -377
- package/components/form/jsonInput/JsonView.vue +54 -56
- package/components/form/jsonInput/index.vue +247 -165
- package/components/form/maskInput/index.vue +252 -132
- package/components/form/numberInput/index.js +0 -1
- package/components/form/numberInput/index.vue +226 -117
- package/components/form/passwordInput/index.js +2 -1
- package/components/form/passwordInput/index.vue +269 -102
- package/components/form/radioInput/index.vue +143 -72
- package/components/form/rangeInput/index.vue +280 -167
- package/components/form/ratingInput/index.vue +57 -57
- package/components/form/selectInput/index.js +1 -3
- package/components/form/selectInput/index.vue +584 -296
- package/components/form/switchInput/index.vue +73 -59
- package/components/form/telInput/index.js +0 -1
- package/components/form/telInput/index.vue +238 -135
- package/components/form/textArea/index.vue +72 -35
- package/components/form/textEditor/index.vue +739 -0
- package/components/form/{text-editor → textEditor}/style.scss +8 -16
- package/components/form/textInput/index.vue +54 -32
- package/components/form/timeInput/index.vue +82 -55
- package/components/form/timeInput/range.vue +115 -94
- package/components/form/timeInput/timepicker.vue +382 -449
- package/components/form/uniqueInput/index.vue +105 -48
- package/components/form/unitInput/index.vue +139 -84
- package/components/formCreator/index.js +0 -1
- package/components/formCreator/index.vue +314 -148
- package/components/highlight/index.vue +41 -25
- package/components/highlight/style.scss +2 -2
- package/components/highlight/{mixin.js → useHighlight.js} +181 -160
- package/components/icon/index.vue +79 -33
- package/components/img/index.vue +250 -147
- package/components/img/preview.vue +180 -198
- package/components/img/svgImg.vue +42 -39
- package/components/index.js +5 -20
- package/components/infinite/index.js +3 -3
- package/components/infinite/index.vue +290 -66
- package/components/map/index.vue +428 -261
- package/components/map/route.vue +794 -487
- package/components/map/select.vue +118 -58
- package/components/menu/index.vue +206 -94
- package/components/meta/meta.js +26 -3
- package/components/modal/index.vue +382 -156
- package/components/notify/index.vue +204 -86
- package/components/notify/notification.vue +38 -55
- package/components/progress/circle.vue +189 -70
- package/components/progress/line.vue +266 -46
- package/components/searchBox/index.js +1 -3
- package/components/searchBox/index.vue +194 -101
- package/components/skeleton/index.vue +45 -20
- package/components/slider/index.vue +319 -156
- package/components/swiper/index.vue +237 -108
- package/components/table/crud/footer.vue +77 -53
- package/components/table/crud/header.vue +71 -72
- package/components/table/crud/index.vue +629 -399
- package/components/table/index.vue +721 -278
- package/components/timeAgo/index.vue +145 -96
- package/components/tour/index.vue +338 -235
- package/components/tree/index.vue +235 -89
- package/components/tree/tree-element.vue +106 -106
- package/directive/animate/index.js +77 -0
- package/directive/clickOutSide/index.js +98 -0
- package/directive/drag/index.js +153 -0
- package/directive/index.js +11 -13
- package/directive/intersect/index.js +263 -0
- package/directive/mask/index.js +67 -0
- package/directive/parallax/index.js +78 -0
- package/directive/ripple/index.js +14 -0
- package/directive/scroll/index.js +272 -24
- package/directive/sortable/index.js +274 -0
- package/directive/title/index.js +75 -0
- package/directive/touch/index.js +268 -0
- package/index.js +11 -19
- package/package.json +5 -2
- package/plugins/validation/Validate.js +88 -79
- package/scripts/generate-docs.mjs +226 -0
- package/scripts/menu.mjs +240 -0
- package/scripts/parser.mjs +1086 -0
- package/style/_index.scss +7 -0
- package/style/app.scss +13 -65
- package/style/colors.scss +5 -22
- package/style/functions/index.scss +8 -0
- package/style/mixins/index.scss +17 -5
- package/style/variables/base.scss +155 -178
- package/style/variables/color.scss +0 -12
- package/style/variables/utilities.scss +0 -180
- package/tools/helper.js +0 -8
- package/tools/icons.js +7 -2
- package/tools/root.js +71 -0
- package/components/app/style.scss +0 -41
- package/components/app/toast/style.scss +0 -20
- package/components/avatar/style.scss +0 -32
- package/components/bar/bottomNav.js +0 -1
- package/components/bar/bottomNav.vue +0 -28
- package/components/bar/bottomNavigationCircle.js +0 -2
- package/components/bar/bottomNavigationCircle.vue +0 -99
- package/components/bar/scss/bottomNav.scss +0 -67
- package/components/bar/scss/toolbar.scss +0 -174
- package/components/bar/toolbar/index.js +0 -8
- package/components/bar/toolbar/index.vue +0 -35
- package/components/bar/toolbar/laptop.vue +0 -33
- package/components/bar/toolbar/menuChilds.vue +0 -41
- package/components/bar/toolbar/menuLaptop.vue +0 -41
- package/components/bar/toolbar/menuMob.vue +0 -39
- package/components/bar/toolbar/mixin.js +0 -43
- package/components/bar/toolbar/mobile.vue +0 -34
- package/components/breadcrumb/bredcrumbItem.vue +0 -39
- package/components/breadcrumb/index.js +0 -3
- package/components/breadcrumb/index.vue +0 -71
- package/components/breadcrumb/style.scss +0 -51
- package/components/button/style.scss +0 -411
- package/components/card/style.scss +0 -86
- package/components/chart/chart.js +0 -1
- package/components/chart/chart.vue +0 -69
- package/components/chart/worldMap.js +0 -2
- package/components/chart/worldMap.vue +0 -1112
- package/components/chat/MessageList.vue +0 -163
- package/components/chat/chatInput.vue +0 -150
- package/components/chat/chatMsg.vue +0 -276
- package/components/chat/index.js +0 -11
- package/components/chat/index.vue +0 -113
- package/components/chip/index.js +0 -3
- package/components/chip/index.vue +0 -77
- package/components/chip/style.scss +0 -199
- package/components/codeEditor/mixin.js +0 -145
- package/components/countdown/index.js +0 -1
- package/components/countdown/index.vue +0 -105
- package/components/form/colorInput/mixin.js +0 -132
- package/components/form/fileInput/file.js +0 -148
- package/components/form/telInput/assets/flags.png +0 -0
- package/components/form/telInput/assets/flags@2x.png +0 -0
- package/components/form/text-editor/index.vue +0 -705
- package/components/icon/style.scss +0 -17
- package/components/infinite/div.js +0 -6
- package/components/infinite/div.vue +0 -193
- package/components/infinite/page.js +0 -3
- package/components/infinite/page.vue +0 -105
- package/components/list/index.js +0 -3
- package/components/list/index.vue +0 -122
- package/components/list/style.scss +0 -66
- package/components/message/index.js +0 -4
- package/components/message/index.vue +0 -40
- package/components/modal/style.scss +0 -146
- package/components/nestable/NestableItem.vue +0 -307
- package/components/nestable/editable.js +0 -44
- package/components/nestable/index.js +0 -1
- package/components/nestable/index.vue +0 -226
- package/components/nestable/methods.js +0 -416
- package/components/progress/style.scss +0 -229
- package/components/table/style.scss +0 -338
- package/components/tabs/index.js +0 -3
- package/components/tabs/index.vue +0 -151
- package/components/timeline/index.js +0 -6
- package/components/timeline/index.vue +0 -76
- package/directive/resize/index.js +0 -30
- package/directive/skeleton/index.js +0 -27
- package/directive/skeleton/style.scss +0 -37
- package/plugins/request/Request.js +0 -68
- package/style/animation.scss +0 -94
- package/style/style.scss +0 -8
- package/tools/rootable.js +0 -75
- /package/components/form/{text-editor → textEditor}/index.js +0 -0
- /package/components/form/{text-editor → textEditor}/preview.js +0 -0
- /package/components/form/{text-editor → textEditor}/preview.vue +0 -0
|
@@ -1,386 +1,659 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<r-input
|
|
3
|
-
<div :class="`${$r.prefix}date-color-input`">
|
|
4
|
-
{{
|
|
2
|
+
<r-input :model-value="displayValue" @click.prevent="show=true">
|
|
3
|
+
<div :class="`${$r.prefix}date-color-input`" class="date-range-display">
|
|
4
|
+
{{ displayValue }}
|
|
5
5
|
</div>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
</r-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</r-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</r-
|
|
40
|
-
</r-
|
|
41
|
-
</r-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
</
|
|
62
|
-
</
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
6
|
+
<r-modal :model-value="show" class="text-center" no-close-btn @update:model-value="close()">
|
|
7
|
+
<div v-if="!showTime" :class="`${$r.prefix}date-input`">
|
|
8
|
+
<div>
|
|
9
|
+
<r-container>
|
|
10
|
+
<r-row>
|
|
11
|
+
<r-col class="col-auto">
|
|
12
|
+
<r-btn v-if="tab!=='month'" icon
|
|
13
|
+
@click.prevent="tab==='day'?incrementMonth(-1):incrementYear(-12)">
|
|
14
|
+
<r-icon v-html="$r.icons.arrow_left"></r-icon>
|
|
15
|
+
</r-btn>
|
|
16
|
+
</r-col>
|
|
17
|
+
<r-col class="text-center">
|
|
18
|
+
<r-btn class="me-2 title-2" text @click.prevent="tab==='month'?tab='day':tab='month'">
|
|
19
|
+
<r-icon v-html="tab==='month'?$r.icons.chevron_up:$r.icons.chevron_down"></r-icon>
|
|
20
|
+
{{
|
|
21
|
+
$d(new
|
|
22
|
+
Date(currentPeriod.year, currentPeriod.month, 1, 0, lang_zone_offset - timezoneOffset), 'month', locale)
|
|
23
|
+
}}
|
|
24
|
+
</r-btn>
|
|
25
|
+
|
|
26
|
+
<r-btn class="title-2" text @click.prevent="tab==='year'?tab='day':tab='year'">
|
|
27
|
+
<r-icon v-html="tab==='year'?$r.icons.chevron_up:$r.icons.chevron_down"></r-icon>
|
|
28
|
+
{{
|
|
29
|
+
$d(new
|
|
30
|
+
Date(currentPeriod.year, currentPeriod.month, 1, 0, lang_zone_offset - timezoneOffset), 'year', locale)
|
|
31
|
+
}}
|
|
32
|
+
</r-btn>
|
|
33
|
+
</r-col>
|
|
34
|
+
<r-col class="col-auto">
|
|
35
|
+
<r-btn v-if="tab!=='month'" icon
|
|
36
|
+
@click.prevent="tab==='day'?incrementMonth(1):incrementYear(12)">
|
|
37
|
+
<r-icon v-html="$r.icons.arrow_right"></r-icon>
|
|
38
|
+
</r-btn>
|
|
39
|
+
</r-col>
|
|
40
|
+
</r-row>
|
|
41
|
+
</r-container>
|
|
42
|
+
|
|
43
|
+
<year v-if="tab==='year'"
|
|
44
|
+
:model-value='currentPeriod.year'
|
|
45
|
+
@update:model-value="(tab='month',incrementYear($event))"
|
|
46
|
+
:timezoneOffset="lang_zone_offset-timezoneOffset"
|
|
47
|
+
:locale="locale"
|
|
48
|
+
:month="currentPeriod.month"></year>
|
|
49
|
+
<month v-if="tab==='month'"
|
|
50
|
+
:model-value='currentPeriod.month'
|
|
51
|
+
@update:model-value="(tab='day',setMonth($event))"
|
|
52
|
+
:timezoneOffset="lang_zone_offset-timezoneOffset"
|
|
53
|
+
:locale="locale"
|
|
54
|
+
:month="currentPeriod.month"
|
|
55
|
+
:year="currentPeriod.year"></month>
|
|
56
|
+
|
|
57
|
+
<div v-if="isRangeMode && rangeSelection.startDate && rangeSelection.endDate" class="range-info">
|
|
58
|
+
<div class="title-3">
|
|
59
|
+
{{ $d(rangeSelection.startDate, withTime ? 'long' : 'medium', locale) }} -
|
|
60
|
+
{{ $d(rangeSelection.endDate, withTime ? 'long' : 'medium', locale) }}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<table v-if="tab==='day'" class="table">
|
|
65
|
+
<thead>
|
|
66
|
+
<tr>
|
|
67
|
+
<th class="headCell" v-for="(weekday, weekdayIndex) in weekDays" :key="weekdayIndex">
|
|
68
|
+
<span class="headCellContent">{{ weekday }}</span>
|
|
69
|
+
</th>
|
|
70
|
+
</tr>
|
|
71
|
+
</thead>
|
|
72
|
+
<transition :name="direction==='next'?'slide-start-to-end':'slide-end-to-start'" mode="out-in">
|
|
73
|
+
<tbody
|
|
74
|
+
:key="currentPeriod.year + '-' + currentPeriod.month"
|
|
75
|
+
>
|
|
76
|
+
<tr class="table-row" v-for="(week, weekIndex) in currentPeriodDates" :key="weekIndex">
|
|
77
|
+
<td
|
|
78
|
+
class="cell"
|
|
79
|
+
v-for="item in week"
|
|
80
|
+
:class="{
|
|
81
|
+
selectable:!item.disabled,
|
|
74
82
|
selected: item.selected,
|
|
83
|
+
'range-start': item.isRangeStart,
|
|
84
|
+
'range-end': item.isRangeEnd,
|
|
85
|
+
'in-range': item.inRange,
|
|
75
86
|
disabled: item.disabled,
|
|
76
87
|
today: item.today
|
|
77
88
|
}"
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
>
|
|
81
|
-
<div
|
|
82
|
-
class="cellContent d-flex h-center v-center"
|
|
83
|
-
v-if="item.date!==0"
|
|
89
|
+
:key="item.date"
|
|
90
|
+
@click.prevent="item.date!==0 &&selectDateItem(item)"
|
|
84
91
|
>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
withSec
|
|
98
|
-
v-model="time"
|
|
99
|
-
></timepicker>
|
|
100
|
-
<div class="mt-5">
|
|
101
|
-
<r-btn class="color-success mx-5" @click.prevent="selectTime">{{ $t('ok', 'renusify') }}</r-btn>
|
|
102
|
-
<r-btn class="color-error mx-5" @click.prevent="close">{{ $t('cancel', 'renusify') }}</r-btn>
|
|
92
|
+
<div
|
|
93
|
+
class="cellContent d-flex h-center v-center"
|
|
94
|
+
v-if="item.date!==0"
|
|
95
|
+
>
|
|
96
|
+
{{ $d(item.date, 'day', locale) }}
|
|
97
|
+
</div>
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
</tbody>
|
|
101
|
+
</transition>
|
|
102
|
+
</table>
|
|
103
|
+
</div>
|
|
103
104
|
</div>
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
<div v-else class="d-flex flex-column h-center v-center pa-5">
|
|
107
|
+
<timepicker
|
|
108
|
+
is24-hour
|
|
109
|
+
withSec
|
|
110
|
+
v-model="time"
|
|
111
|
+
></timepicker>
|
|
112
|
+
<div class="mt-5">
|
|
113
|
+
<r-btn class="color-success mx-5" @click.prevent="selectTime">{{ $t('ok', 'renusify') }}</r-btn>
|
|
114
|
+
<r-btn class="color-error mx-5" @click.prevent="close">{{ $t('cancel', 'renusify') }}</r-btn>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
108
117
|
|
|
118
|
+
<div v-if="isRangeMode&&!showTime" class="date-picker-actions mb-3">
|
|
119
|
+
<r-btn class="color-one mx-5" @click.prevent="confirmRange">{{ $t('confirm', 'renusify') }}</r-btn>
|
|
120
|
+
<r-btn class="mx-5" text @click.prevent="resetRange">{{ $t('reset', 'renusify') }}</r-btn>
|
|
121
|
+
</div>
|
|
122
|
+
</r-modal>
|
|
123
|
+
</r-input>
|
|
109
124
|
</template>
|
|
110
125
|
|
|
111
|
-
<script>
|
|
112
|
-
import {
|
|
126
|
+
<script setup>
|
|
127
|
+
import {ref, computed, watch, inject} from 'vue'
|
|
128
|
+
import Timepicker from "../timeInput/timepicker.vue";
|
|
129
|
+
import Year from "./year.vue";
|
|
130
|
+
import Month from "./month.vue";
|
|
131
|
+
|
|
132
|
+
const props = defineProps({
|
|
133
|
+
/**
|
|
134
|
+
* The model value for the date picker (v-model)
|
|
135
|
+
* @type {String|Array}
|
|
136
|
+
*/
|
|
137
|
+
modelValue: {
|
|
138
|
+
type: [String, Array]
|
|
139
|
+
},
|
|
113
140
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Language/locale for date formatting
|
|
143
|
+
* @type {String}
|
|
144
|
+
*/
|
|
145
|
+
lang: {
|
|
146
|
+
type: String
|
|
120
147
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Enables time selection alongside date selection
|
|
151
|
+
* @type {Boolean}
|
|
152
|
+
*/
|
|
153
|
+
withTime: Boolean,
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Enables date range selection mode
|
|
157
|
+
* @type {Boolean}
|
|
158
|
+
* @default false
|
|
159
|
+
*/
|
|
160
|
+
rangeMode: {
|
|
161
|
+
type: Boolean,
|
|
162
|
+
default: false
|
|
135
163
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Function to determine if a date should be disabled
|
|
167
|
+
* @type {Function}
|
|
168
|
+
* @default () => false
|
|
169
|
+
* @param {Date} date - The date to check
|
|
170
|
+
* @returns {Boolean} True if the date should be disabled
|
|
171
|
+
*/
|
|
172
|
+
isDateDisabled: {
|
|
173
|
+
type: Function,
|
|
174
|
+
default: () => false
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
const emit = defineEmits([
|
|
179
|
+
/**
|
|
180
|
+
* Emitted when the date value changes
|
|
181
|
+
* @param {String|Array} value - The new date value(s)
|
|
182
|
+
*/
|
|
183
|
+
'update:modelValue'
|
|
184
|
+
])
|
|
185
|
+
|
|
186
|
+
const {$dateTime, $helper, $r, $d} = inject('renusify')
|
|
187
|
+
|
|
188
|
+
const tab = ref('day')
|
|
189
|
+
const show = ref(false)
|
|
190
|
+
const showTime = ref(false)
|
|
191
|
+
const time = ref(null)
|
|
192
|
+
const date = ref(null)
|
|
193
|
+
const direction = ref(undefined)
|
|
194
|
+
const timeSelectionType = ref('start')
|
|
195
|
+
|
|
196
|
+
const currentPeriod = ref({
|
|
197
|
+
month: new Date().getMonth() + 1,
|
|
198
|
+
year: new Date().getFullYear()
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const rangeSelection = ref({
|
|
202
|
+
startDate: null,
|
|
203
|
+
endDate: null,
|
|
204
|
+
selecting: false
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
const TODAY = new Date()
|
|
208
|
+
|
|
209
|
+
const locale = computed(() => props.lang || $r.lang)
|
|
210
|
+
const firstDayOfWeek = computed(() =>
|
|
211
|
+
$helper.ifHas($dateTime.langs, 0, locale.value, 'first_day')
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
const modelValueDate = computed(() => {
|
|
215
|
+
if (props.isRangeMode && rangeSelection.value.startDate) {
|
|
216
|
+
return rangeSelection.value.startDate
|
|
217
|
+
}
|
|
218
|
+
if (!props.modelValue || !new Date(props.modelValue)) {
|
|
219
|
+
return new Date()
|
|
220
|
+
}
|
|
221
|
+
return new Date(props.modelValue)
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
const timezoneOffset = computed(() =>
|
|
225
|
+
new Date(currentPeriod.value.year, currentPeriod.value.month, 10).getTimezoneOffset()
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
const lang_zone_offset = computed(() =>
|
|
229
|
+
$helper.ifHas($dateTime.langs, 0, locale.value, 'time_zone_offset') * -1
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
const displayValue = computed(() => {
|
|
233
|
+
if (props.isRangeMode) {
|
|
234
|
+
const {startDate, endDate} = rangeSelection.value
|
|
235
|
+
if (startDate && endDate) {
|
|
236
|
+
const format = props.withTime ? 'long' : 'medium'
|
|
237
|
+
return `${$d(startDate, format, locale.value)} - ${$d(endDate, format, locale.value)}`
|
|
149
238
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
239
|
+
return null
|
|
240
|
+
}
|
|
241
|
+
return props.modelValue ? $d(modelValueDate.value, props.withTime ? 'long' : 'medium', locale.value) : null
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
const weekDays = computed(() => {
|
|
245
|
+
const first = parseInt(firstDayOfWeek.value, 10)
|
|
246
|
+
return createRange(7).map(i =>
|
|
247
|
+
$d(new Date(2025, 2, first + i + 23, 0, lang_zone_offset.value - timezoneOffset.value, 0), 'narrow', locale.value)
|
|
248
|
+
)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
const rangeLocalDate = computed(() => {
|
|
252
|
+
const {year, month} = currentPeriod.value
|
|
253
|
+
|
|
254
|
+
const firstDayOfMonth = new Date(year, month, 1, 0, lang_zone_offset.value - timezoneOffset.value, 0)
|
|
255
|
+
const firstDayWeekday = parseInt($d(firstDayOfMonth, 'de', locale.value))
|
|
256
|
+
const calendarStart = new Date(year, month, 1 - firstDayWeekday + 1, 0, lang_zone_offset.value - timezoneOffset.value, 0)
|
|
257
|
+
|
|
258
|
+
const firstDayNextMonth = new Date(year, month + 1, 1, 0, lang_zone_offset.value - timezoneOffset.value, 0)
|
|
259
|
+
const firstDayNextMonthWeekday = parseInt($d(firstDayNextMonth, 'de', locale.value))
|
|
260
|
+
const calendarEnd = new Date(year, month + 1, 1 - firstDayNextMonthWeekday, 23, 59 + lang_zone_offset.value - timezoneOffset.value, 59)
|
|
261
|
+
|
|
262
|
+
return {start: calendarStart, end: calendarEnd}
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
const weekDaysBeforeFirstDayOfTheMonth = computed(() => {
|
|
266
|
+
const {start} = rangeLocalDate.value
|
|
267
|
+
const weekDay = start.getDay()
|
|
268
|
+
return (weekDay - parseInt(firstDayOfWeek.value) + 7) % 7
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
const currentPeriodDates = computed(() => {
|
|
272
|
+
const {start, end} = rangeLocalDate.value
|
|
273
|
+
|
|
274
|
+
function* dateGenerator() {
|
|
275
|
+
const current = new Date(start)
|
|
276
|
+
while (current <= end) {
|
|
277
|
+
yield new Date(current)
|
|
278
|
+
current.setDate(current.getDate() + 1)
|
|
169
279
|
}
|
|
170
|
-
|
|
171
|
-
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const weeks = []
|
|
283
|
+
let currentWeek = []
|
|
284
|
+
|
|
285
|
+
const leadingEmptyDays = weekDaysBeforeFirstDayOfTheMonth.value
|
|
286
|
+
currentWeek.push(...Array(leadingEmptyDays).fill(null).map(() => createEmptyDateCell(null)))
|
|
287
|
+
|
|
288
|
+
for (const date of dateGenerator()) {
|
|
289
|
+
currentWeek.push(createDateCell(date))
|
|
290
|
+
|
|
291
|
+
if (currentWeek.length === 7) {
|
|
292
|
+
weeks.push(currentWeek)
|
|
293
|
+
currentWeek = []
|
|
172
294
|
}
|
|
173
|
-
|
|
174
|
-
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (currentWeek.length > 0) {
|
|
298
|
+
const trailingEmptyDays = 7 - currentWeek.length
|
|
299
|
+
currentWeek.push(...Array(trailingEmptyDays).fill(null).map(() => createEmptyDateCell(null)))
|
|
300
|
+
weeks.push(currentWeek)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return weeks
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const createRange = (number) => Array.from({length: number}, (_, i) => i)
|
|
307
|
+
|
|
308
|
+
const createEmptyDateCell = () => ({
|
|
309
|
+
date: 0,
|
|
310
|
+
disabled: true,
|
|
311
|
+
selected: false,
|
|
312
|
+
today: false,
|
|
313
|
+
isRangeStart: false,
|
|
314
|
+
isRangeEnd: false,
|
|
315
|
+
inRange: false
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
const createDateCell = (date) => {
|
|
319
|
+
const cell = {
|
|
320
|
+
date,
|
|
321
|
+
disabled: props.isDateDisabled(date),
|
|
322
|
+
selected: areSameDates(date, modelValueDate.value),
|
|
323
|
+
today: areSameDates(date, TODAY),
|
|
324
|
+
isRangeStart: false,
|
|
325
|
+
isRangeEnd: false,
|
|
326
|
+
inRange: false
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (props.isRangeMode) {
|
|
330
|
+
cell.isRangeStart = rangeSelection.value.startDate ? areSameDates(date, rangeSelection.value.startDate) : false
|
|
331
|
+
cell.isRangeEnd = rangeSelection.value.endDate ? areSameDates(date, rangeSelection.value.endDate) : false
|
|
332
|
+
cell.inRange = isDateInRange(date)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return cell
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Checks if two dates are the same day
|
|
340
|
+
* @param {Date} date1 - First date
|
|
341
|
+
* @param {Date} date2 - Second date
|
|
342
|
+
* @returns {Boolean} True if dates are the same day
|
|
343
|
+
*/
|
|
344
|
+
const areSameDates = (date1, date2) => {
|
|
345
|
+
if (!date1 || !date2 || typeof date1.getDate !== 'function' || typeof date2.getDate !== 'function') {
|
|
346
|
+
return false
|
|
347
|
+
}
|
|
348
|
+
return date1.getDate() === date2.getDate() &&
|
|
349
|
+
date1.getMonth() === date2.getMonth() &&
|
|
350
|
+
date1.getFullYear() === date2.getFullYear()
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Checks if a date is within the selected range
|
|
355
|
+
* @param {Date} date - Date to check
|
|
356
|
+
* @returns {Boolean} True if date is within range
|
|
357
|
+
*/
|
|
358
|
+
const isDateInRange = (date) => {
|
|
359
|
+
const {startDate, endDate} = rangeSelection.value
|
|
360
|
+
if (!startDate || !endDate) return false
|
|
361
|
+
return date > startDate && date < endDate
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Increments the current month view
|
|
366
|
+
* @param {Number} increment - Number of months to increment
|
|
367
|
+
*/
|
|
368
|
+
const incrementMonth = (increment = 1) => {
|
|
369
|
+
const incrementDate = new Date(currentPeriod.value.year, currentPeriod.value.month + increment)
|
|
370
|
+
currentPeriod.value = {
|
|
371
|
+
month: incrementDate.getMonth(),
|
|
372
|
+
year: incrementDate.getFullYear()
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Increments the current year view
|
|
378
|
+
* @param {Number} increment - Number of years to increment
|
|
379
|
+
*/
|
|
380
|
+
const incrementYear = (increment = 1) => {
|
|
381
|
+
const incrementDate = new Date(currentPeriod.value.year + increment, currentPeriod.value.month)
|
|
382
|
+
currentPeriod.value = {
|
|
383
|
+
month: incrementDate.getMonth(),
|
|
384
|
+
year: incrementDate.getFullYear()
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Sets the current month view
|
|
390
|
+
* @param {Number} monthIndex - Month index (0-11)
|
|
391
|
+
*/
|
|
392
|
+
const setMonth = (monthIndex) => {
|
|
393
|
+
const incrementDate = new Date(currentPeriod.value.year, monthIndex)
|
|
394
|
+
currentPeriod.value = {
|
|
395
|
+
month: incrementDate.getMonth(),
|
|
396
|
+
year: incrementDate.getFullYear()
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Closes the date picker
|
|
402
|
+
* @param {Boolean} force - Force close even in range mode
|
|
403
|
+
*/
|
|
404
|
+
const close = (force = false) => {
|
|
405
|
+
if (force || !props.isRangeMode) {
|
|
406
|
+
show.value = false
|
|
407
|
+
}
|
|
408
|
+
showTime.value = false
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Handles time selection
|
|
413
|
+
*/
|
|
414
|
+
const selectTime = () => {
|
|
415
|
+
const times = (time.value ? time.value : '00:00:00').split(':')
|
|
416
|
+
const [hours, minutes, seconds] = times.map(t => parseInt(t))
|
|
417
|
+
|
|
418
|
+
if (props.isRangeMode) {
|
|
419
|
+
handleRangeTimeSelection(hours, minutes, seconds)
|
|
420
|
+
} else {
|
|
421
|
+
handleSingleTimeSelection(hours, minutes, seconds)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Handles time selection for range mode
|
|
427
|
+
* @param {Number} hours - Selected hours
|
|
428
|
+
* @param {Number} minutes - Selected minutes
|
|
429
|
+
* @param {Number} seconds - Selected seconds
|
|
430
|
+
*/
|
|
431
|
+
const handleRangeTimeSelection = (hours, minutes, seconds) => {
|
|
432
|
+
if (timeSelectionType.value === 'start') {
|
|
433
|
+
const startDate = new Date(rangeSelection.value.startDate)
|
|
434
|
+
startDate.setHours(hours, minutes, seconds)
|
|
435
|
+
rangeSelection.value.startDate = startDate
|
|
436
|
+
|
|
437
|
+
if (rangeSelection.value.endDate) {
|
|
438
|
+
timeSelectionType.value = 'end'
|
|
439
|
+
const endDate = rangeSelection.value.endDate
|
|
440
|
+
time.value = formatTime(endDate.getHours(), endDate.getMinutes(), endDate.getSeconds())
|
|
175
441
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
today() {
|
|
185
|
-
return new Date()
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
weekDays() {
|
|
189
|
-
const first = parseInt(this.firstDayOfWeek, 10)
|
|
190
|
-
|
|
191
|
-
return this.createRange(7).map(i => this.$d(new Date(2025, 2, first + i + 23, 0, this.lang_zone_offset - this.timezoneOffset, 0), 'narrow', this.locale)) // 2017-02-02 is Sunday
|
|
192
|
-
},
|
|
193
|
-
modelValueDate() {
|
|
194
|
-
if (!this.modelValue || !new Date(this.modelValue)) {
|
|
195
|
-
return new Date()
|
|
196
|
-
}
|
|
197
|
-
return new Date(this.modelValue)
|
|
198
|
-
},
|
|
199
|
-
rangeLocalDate() {
|
|
200
|
-
const {year, month} = this.currentPeriod
|
|
201
|
-
let firstDay = 1
|
|
202
|
-
let firstmonth = month
|
|
203
|
-
let firstyear = year
|
|
204
|
-
let first = new Date(firstyear, firstmonth, firstDay, 0, this.lang_zone_offset - this.timezoneOffset, 0)
|
|
205
|
-
let lc = parseInt(this.$d(first, 'de', this.locale))
|
|
206
|
-
first = new Date(firstyear, firstmonth, firstDay - lc + 1, 0, this.lang_zone_offset - this.timezoneOffset, 0)
|
|
207
|
-
|
|
208
|
-
firstDay = 1
|
|
209
|
-
firstmonth = month + 1
|
|
210
|
-
firstyear = year
|
|
211
|
-
let last = new Date(firstyear, firstmonth, firstDay, 0, this.lang_zone_offset - this.timezoneOffset, 0)
|
|
212
|
-
lc = parseInt(this.$d(last, 'de', this.locale))
|
|
213
|
-
last = new Date(firstyear, firstmonth, firstDay - lc, 23, 59 + this.lang_zone_offset - this.timezoneOffset, 59)
|
|
214
|
-
|
|
215
|
-
return {start: first, end: last}
|
|
216
|
-
},
|
|
217
|
-
weekDaysBeforeFirstDayOfTheMonth() {
|
|
218
|
-
const {start} = this.rangeLocalDate
|
|
219
|
-
const weekDay = start.getDay()
|
|
220
|
-
return (weekDay - parseInt(this.firstDayOfWeek) + 7) % 7
|
|
221
|
-
},
|
|
222
|
-
currentPeriodDates() {
|
|
223
|
-
const {start, end} = this.rangeLocalDate
|
|
224
|
-
const children = []
|
|
225
|
-
let firstday = start.getDate()
|
|
226
|
-
let firstmonth = start.getMonth()
|
|
227
|
-
let firstyear = start.getFullYear()
|
|
228
|
-
let rows = []
|
|
229
|
-
let day = this.weekDaysBeforeFirstDayOfTheMonth
|
|
230
|
-
|
|
231
|
-
while (day--) {
|
|
232
|
-
rows.push({
|
|
233
|
-
date: 0,
|
|
234
|
-
disabled: true,
|
|
235
|
-
selected: false,
|
|
236
|
-
today: false
|
|
237
|
-
})
|
|
238
|
-
}
|
|
239
|
-
let doJob = true
|
|
240
|
-
while (doJob) {
|
|
241
|
-
const date = new Date(firstyear, firstmonth, 1, 24, this.lang_zone_offset - this.timezoneOffset, 0)
|
|
242
|
-
date.setDate(firstday)
|
|
243
|
-
firstmonth = date.getMonth()
|
|
244
|
-
firstyear = date.getFullYear()
|
|
245
|
-
firstday = date.getDate() + 1
|
|
246
|
-
if (date.getTime() > end.getTime()) {
|
|
247
|
-
doJob = false
|
|
248
|
-
} else {
|
|
249
|
-
rows.push({
|
|
250
|
-
date: date,
|
|
251
|
-
disabled: this.isDateDisabled(date),
|
|
252
|
-
selected: this.areSameDates(date, this.modelValueDate),
|
|
253
|
-
today: this.areSameDates(date, this.today)
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
if (rows.length % 7 === 0) {
|
|
257
|
-
children.push(rows)
|
|
258
|
-
rows = []
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
442
|
+
close()
|
|
443
|
+
} else {
|
|
444
|
+
const endDate = new Date(rangeSelection.value.endDate)
|
|
445
|
+
endDate.setHours(hours, minutes, seconds)
|
|
446
|
+
rangeSelection.value.endDate = endDate
|
|
447
|
+
close()
|
|
448
|
+
}
|
|
449
|
+
}
|
|
262
450
|
|
|
263
|
-
|
|
264
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Handles time selection for single date mode
|
|
453
|
+
* @param {Number} hours - Selected hours
|
|
454
|
+
* @param {Number} minutes - Selected minutes
|
|
455
|
+
* @param {Number} seconds - Selected seconds
|
|
456
|
+
*/
|
|
457
|
+
const handleSingleTimeSelection = (hours, minutes, seconds) => {
|
|
458
|
+
const selectedDate = new Date(date.value)
|
|
459
|
+
selectedDate.setHours(hours, minutes, seconds)
|
|
460
|
+
emit('update:modelValue', selectedDate.toISOString())
|
|
461
|
+
close()
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Formats time components to HH:MM:SS string
|
|
466
|
+
* @param {Number} hours - Hours
|
|
467
|
+
* @param {Number} minutes - Minutes
|
|
468
|
+
* @param {Number} seconds - Seconds
|
|
469
|
+
* @returns {String} Formatted time string
|
|
470
|
+
*/
|
|
471
|
+
const formatTime = (hours, minutes, seconds) => {
|
|
472
|
+
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Handles date selection
|
|
477
|
+
* @param {Object} item - Date cell object
|
|
478
|
+
*/
|
|
479
|
+
const selectDateItem = (item) => {
|
|
480
|
+
if (!item.disabled) {
|
|
481
|
+
if (props.isRangeMode) {
|
|
482
|
+
handleRangeSelection(item.date)
|
|
483
|
+
} else {
|
|
484
|
+
if (props.withTime) {
|
|
485
|
+
date.value = item.date
|
|
486
|
+
showTime.value = true
|
|
487
|
+
} else {
|
|
488
|
+
emit('update:modelValue', item.date.toISOString())
|
|
489
|
+
close()
|
|
265
490
|
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
266
494
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Handles date range selection
|
|
497
|
+
* @param {Date} date - Selected date
|
|
498
|
+
*/
|
|
499
|
+
const handleRangeSelection = (date) => {
|
|
500
|
+
if (!rangeSelection.value.selecting) {
|
|
501
|
+
rangeSelection.value = {
|
|
502
|
+
startDate: date,
|
|
503
|
+
endDate: null,
|
|
504
|
+
selecting: true
|
|
274
505
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
year: newVal.getFullYear()
|
|
281
|
-
}
|
|
282
|
-
if (this.rangeLocalDate.start > this.modelValueDate) {
|
|
283
|
-
this.incrementMonth(-1)
|
|
284
|
-
}
|
|
285
|
-
if (this.rangeLocalDate.end < this.modelValueDate) {
|
|
286
|
-
this.incrementMonth(1)
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
currentPeriod(currentPeriod, oldPeriod) {
|
|
290
|
-
const currentDate = new Date(currentPeriod.year, currentPeriod.month).getTime()
|
|
291
|
-
const oldDate = new Date(oldPeriod.year, oldPeriod.month).getTime()
|
|
292
|
-
this.direction = currentDate !== oldDate
|
|
293
|
-
? (currentDate > oldDate ? 'next' : 'prev')
|
|
294
|
-
: undefined
|
|
506
|
+
|
|
507
|
+
if (props.withTime) {
|
|
508
|
+
timeSelectionType.value = 'start'
|
|
509
|
+
showTime.value = true
|
|
510
|
+
time.value = formatTime(date.getHours(), date.getMinutes(), date.getSeconds())
|
|
295
511
|
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
year: incrementDate.getFullYear()
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
incrementYear(increment = 1) {
|
|
317
|
-
const incrementDate = new Date(this.currentPeriod.year + increment, this.currentPeriod.month)
|
|
318
|
-
this.currentPeriod = {
|
|
319
|
-
month: incrementDate.getMonth(),
|
|
320
|
-
year: incrementDate.getFullYear()
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
setMonth(increment) {
|
|
324
|
-
const incrementDate = new Date(this.currentPeriod.year, increment)
|
|
325
|
-
this.currentPeriod = {
|
|
326
|
-
month: incrementDate.getMonth(),
|
|
327
|
-
year: incrementDate.getFullYear()
|
|
328
|
-
}
|
|
329
|
-
},
|
|
330
|
-
selectTime() {
|
|
331
|
-
const times = (this.time ? this.time : '00:00:00').split(':')
|
|
332
|
-
let d = (new Date(this.date.getFullYear(), this.date.getMonth(), this.date.getDate(),
|
|
333
|
-
this.date.getHours() + parseInt(times[0]),
|
|
334
|
-
this.date.getMinutes() + parseInt(times[1]),
|
|
335
|
-
this.date.getSeconds() + parseInt(times[2])))
|
|
336
|
-
|
|
337
|
-
this.$emit('update:modelValue', d.toISOString())
|
|
338
|
-
this.close()
|
|
339
|
-
},
|
|
340
|
-
selectDateItem(item) {
|
|
341
|
-
if (!item.disabled) {
|
|
342
|
-
if (this.withTime) {
|
|
343
|
-
this.date = item.date
|
|
344
|
-
this.showTime = true
|
|
345
|
-
} else {
|
|
346
|
-
this.$emit('update:modelValue', item.date.toISOString())
|
|
347
|
-
this.close()
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
},
|
|
351
|
-
areSameDates(date1, date2) {
|
|
352
|
-
if (typeof date1.getDate === 'function' && typeof date2.getDate === 'function') {
|
|
353
|
-
return (date1.getDate() === date2.getDate()) &&
|
|
354
|
-
(date1.getMonth() === date2.getMonth()) &&
|
|
355
|
-
(date1.getFullYear() === date2.getFullYear())
|
|
356
|
-
}
|
|
357
|
-
return false
|
|
512
|
+
} else {
|
|
513
|
+
const newRange = {...rangeSelection.value}
|
|
514
|
+
|
|
515
|
+
if (date < newRange.startDate) {
|
|
516
|
+
newRange.endDate = newRange.startDate
|
|
517
|
+
newRange.startDate = date
|
|
518
|
+
} else {
|
|
519
|
+
newRange.endDate = date
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
newRange.selecting = false
|
|
523
|
+
rangeSelection.value = newRange
|
|
524
|
+
|
|
525
|
+
if (props.withTime) {
|
|
526
|
+
timeSelectionType.value = 'end'
|
|
527
|
+
showTime.value = true
|
|
528
|
+
time.value = formatTime(newRange.endDate.getHours(), newRange.endDate.getMinutes(), newRange.endDate.getSeconds())
|
|
358
529
|
}
|
|
359
530
|
}
|
|
360
531
|
}
|
|
361
532
|
|
|
533
|
+
/**
|
|
534
|
+
* Confirms the selected date range
|
|
535
|
+
*/
|
|
536
|
+
const confirmRange = () => {
|
|
537
|
+
const {startDate, endDate} = rangeSelection.value
|
|
538
|
+
if (startDate && endDate) {
|
|
539
|
+
emit('update:modelValue', [
|
|
540
|
+
startDate.toISOString(),
|
|
541
|
+
endDate.toISOString()
|
|
542
|
+
])
|
|
543
|
+
close(true)
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Resets the date range selection
|
|
549
|
+
*/
|
|
550
|
+
const resetRange = () => {
|
|
551
|
+
rangeSelection.value = {
|
|
552
|
+
startDate: null,
|
|
553
|
+
endDate: null,
|
|
554
|
+
selecting: false
|
|
555
|
+
}
|
|
556
|
+
timeSelectionType.value = 'start'
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
watch(modelValueDate, (newVal) => {
|
|
560
|
+
currentPeriod.value = {
|
|
561
|
+
month: newVal.getMonth() + 1,
|
|
562
|
+
year: newVal.getFullYear()
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const {start, end} = rangeLocalDate.value
|
|
566
|
+
if (start > newVal) incrementMonth(-1)
|
|
567
|
+
if (end < newVal) incrementMonth(1)
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
watch(currentPeriod, (newPeriod, oldPeriod) => {
|
|
571
|
+
const currentDate = new Date(newPeriod.year, newPeriod.month).getTime()
|
|
572
|
+
const oldDate = new Date(oldPeriod.year, oldPeriod.month).getTime()
|
|
573
|
+
direction.value = currentDate !== oldDate
|
|
574
|
+
? (currentDate > oldDate ? 'next' : 'prev')
|
|
575
|
+
: undefined
|
|
576
|
+
})
|
|
577
|
+
|
|
578
|
+
$dateTime.set_format({
|
|
579
|
+
'de': {day: 'numeric', numberingSystem: 'latn'},
|
|
580
|
+
'me': {month: 'numeric', numberingSystem: 'latn'},
|
|
581
|
+
'ye': {year: 'numeric', numberingSystem: 'latn'}
|
|
582
|
+
})
|
|
583
|
+
|
|
584
|
+
if (props.isRangeMode && Array.isArray(props.modelValue) && props.modelValue.length === 2) {
|
|
585
|
+
rangeSelection.value = {
|
|
586
|
+
startDate: new Date(props.modelValue[0]),
|
|
587
|
+
endDate: new Date(props.modelValue[1]),
|
|
588
|
+
selecting: false
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const {start, end} = rangeLocalDate.value
|
|
593
|
+
if (start > modelValueDate.value) incrementMonth(-1)
|
|
594
|
+
if (end < modelValueDate.value) incrementMonth(1)
|
|
362
595
|
</script>
|
|
363
596
|
|
|
364
597
|
<style lang="scss">
|
|
365
|
-
@use "../../../style
|
|
598
|
+
@use "../../../style" as *;
|
|
366
599
|
|
|
367
|
-
.#{
|
|
600
|
+
.#{$prefix}date-color-input {
|
|
368
601
|
color: var(--color-on-sheet);
|
|
602
|
+
|
|
603
|
+
&.date-range-display {
|
|
604
|
+
font-weight: 500;
|
|
605
|
+
}
|
|
369
606
|
}
|
|
370
|
-
|
|
607
|
+
|
|
608
|
+
.#{$prefix}date-input {
|
|
371
609
|
position: relative;
|
|
372
610
|
display: inline-block;
|
|
373
611
|
font-size: 10px;
|
|
374
|
-
|
|
375
|
-
|
|
612
|
+
border-radius: 12px;
|
|
613
|
+
padding: 16px;
|
|
614
|
+
overflow: hidden;
|
|
615
|
+
|
|
616
|
+
.date-picker-header {
|
|
617
|
+
margin-bottom: 16px;
|
|
618
|
+
padding-bottom: 12px;
|
|
619
|
+
border-bottom: 1px solid var(--color-border-low);
|
|
620
|
+
|
|
621
|
+
h3 {
|
|
622
|
+
margin: 0;
|
|
623
|
+
color: var(--color-one);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.range-info {
|
|
628
|
+
margin: 12px 0;
|
|
629
|
+
padding: 12px;
|
|
630
|
+
background-color: var(--color-one-container);
|
|
631
|
+
border-radius: 8px;
|
|
632
|
+
color: var(--color-on-one-container);
|
|
633
|
+
|
|
634
|
+
.body-2 {
|
|
635
|
+
margin-bottom: 4px;
|
|
636
|
+
opacity: 0.8;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.date-picker-actions {
|
|
641
|
+
display: flex;
|
|
642
|
+
justify-content: space-between;
|
|
643
|
+
margin-top: 16px;
|
|
644
|
+
padding-top: 12px;
|
|
645
|
+
border-top: 1px solid var(--color-border-low);
|
|
646
|
+
}
|
|
376
647
|
|
|
377
648
|
.date-picker-year {
|
|
378
649
|
max-height: 300px;
|
|
650
|
+
overflow: auto;
|
|
379
651
|
}
|
|
380
652
|
|
|
381
653
|
.cell {
|
|
382
654
|
&.today {
|
|
383
655
|
color: var(--color-one);
|
|
656
|
+
font-weight: 600;
|
|
384
657
|
|
|
385
658
|
.cellContent {
|
|
386
659
|
border: solid 1px var(--color-one);
|
|
@@ -391,56 +664,69 @@ export default {
|
|
|
391
664
|
.cellContent {
|
|
392
665
|
color: var(--color-on-one);
|
|
393
666
|
background: var(--color-one);
|
|
667
|
+
font-weight: 600;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
394
670
|
|
|
671
|
+
&.range-start {
|
|
672
|
+
.cellContent {
|
|
673
|
+
color: var(--color-on-one) !important;
|
|
674
|
+
background: var(--color-one) !important;
|
|
675
|
+
font-weight: 600;
|
|
395
676
|
}
|
|
396
677
|
}
|
|
397
678
|
|
|
398
|
-
&.
|
|
679
|
+
&.range-end {
|
|
680
|
+
.cellContent {
|
|
681
|
+
color: var(--color-on-one) !important;
|
|
682
|
+
background: var(--color-one) !important;
|
|
683
|
+
font-weight: 600;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
&.in-range {
|
|
399
688
|
.cellContent {
|
|
689
|
+
background: var(--color-one-container);
|
|
690
|
+
color: var(--color-on-one-container);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
400
693
|
|
|
694
|
+
&.selectable:hover {
|
|
695
|
+
.cellContent {
|
|
401
696
|
color: var(--color-on-one);
|
|
402
697
|
background: var(--color-one);
|
|
403
|
-
|
|
404
698
|
}
|
|
405
699
|
}
|
|
406
|
-
|
|
407
700
|
}
|
|
408
701
|
|
|
409
|
-
|
|
410
702
|
.table {
|
|
411
|
-
|
|
412
703
|
width: 100%;
|
|
413
704
|
table-layout: fixed;
|
|
414
705
|
position: relative;
|
|
415
706
|
z-index: 5;
|
|
416
|
-
|
|
707
|
+
margin-top: 16px;
|
|
417
708
|
}
|
|
418
709
|
|
|
419
710
|
.cell, .headCell {
|
|
420
|
-
|
|
421
711
|
text-align: center;
|
|
422
712
|
box-sizing: border-box;
|
|
423
|
-
|
|
424
713
|
}
|
|
425
714
|
|
|
426
715
|
.cell {
|
|
427
|
-
|
|
428
716
|
padding: 0.5em 0;
|
|
429
|
-
|
|
717
|
+
position: relative;
|
|
430
718
|
}
|
|
431
719
|
|
|
432
720
|
.headCell {
|
|
433
|
-
|
|
434
721
|
padding: 0.3em 0.5em 1.8em;
|
|
435
|
-
|
|
436
722
|
}
|
|
437
723
|
|
|
438
724
|
.headCellContent {
|
|
439
|
-
|
|
440
725
|
font-size: 1.3em;
|
|
441
|
-
font-weight:
|
|
726
|
+
font-weight: 600;
|
|
442
727
|
color: var(--color-on-sheet-low);
|
|
443
|
-
|
|
728
|
+
text-transform: uppercase;
|
|
729
|
+
letter-spacing: 0.5px;
|
|
444
730
|
}
|
|
445
731
|
|
|
446
732
|
.cellContent {
|
|
@@ -451,8 +737,55 @@ export default {
|
|
|
451
737
|
height: 30px;
|
|
452
738
|
text-align: center;
|
|
453
739
|
border-radius: 100%;
|
|
454
|
-
transition:
|
|
740
|
+
transition: all 0.2s ease;
|
|
741
|
+
position: relative;
|
|
742
|
+
z-index: 2;
|
|
743
|
+
}
|
|
455
744
|
|
|
745
|
+
.cell.in-range::after {
|
|
746
|
+
content: '';
|
|
747
|
+
position: absolute;
|
|
748
|
+
top: 0;
|
|
749
|
+
bottom: 0;
|
|
750
|
+
left: 0;
|
|
751
|
+
right: 0;
|
|
752
|
+
background: var(--color-one-container);
|
|
753
|
+
z-index: 1;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.cell.range-start::after {
|
|
757
|
+
content: '';
|
|
758
|
+
position: absolute;
|
|
759
|
+
top: 0;
|
|
760
|
+
bottom: 0;
|
|
761
|
+
background: var(--color-one-container);
|
|
762
|
+
z-index: 1;
|
|
763
|
+
@include ltr() {
|
|
764
|
+
left: 50%;
|
|
765
|
+
right: 0;
|
|
766
|
+
}
|
|
767
|
+
@include rtl() {
|
|
768
|
+
left: 0;
|
|
769
|
+
right: 50%;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
.cell.range-end::after {
|
|
774
|
+
content: '';
|
|
775
|
+
position: absolute;
|
|
776
|
+
top: 0;
|
|
777
|
+
bottom: 0;
|
|
778
|
+
background: var(--color-one-container);
|
|
779
|
+
z-index: 1;
|
|
780
|
+
@include ltr() {
|
|
781
|
+
left: 0;
|
|
782
|
+
right: 50%;
|
|
783
|
+
}
|
|
784
|
+
@include rtl() {
|
|
785
|
+
left: 50%;
|
|
786
|
+
right: 0;
|
|
787
|
+
|
|
788
|
+
}
|
|
456
789
|
}
|
|
457
790
|
|
|
458
791
|
.cell.outOfRange {
|
|
@@ -460,14 +793,16 @@ export default {
|
|
|
460
793
|
}
|
|
461
794
|
|
|
462
795
|
.cell.selectable {
|
|
463
|
-
|
|
464
796
|
cursor: pointer;
|
|
465
|
-
|
|
466
797
|
}
|
|
467
798
|
|
|
468
799
|
.cell.disabled {
|
|
469
800
|
opacity: 0.38;
|
|
470
801
|
}
|
|
802
|
+
}
|
|
471
803
|
|
|
804
|
+
.time-selection-title {
|
|
805
|
+
color: var(--color-one);
|
|
806
|
+
font-weight: 600;
|
|
472
807
|
}
|
|
473
808
|
</style>
|