@afeefa/vue-app 0.0.145 → 0.0.146

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- 0.0.145
1
+ 0.0.146
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.145",
3
+ "version": "0.0.146",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
7
+ "dependencies": {
8
+ "moment": "^2.29.1"
9
+ },
7
10
  "devDependencies": {
8
11
  "core-js": "^3.25.5",
9
12
  "vue": "^2.7.10",
@@ -172,6 +172,10 @@ export default class AContextMenu extends Mixins(UsesPositionServiceMixin) {
172
172
  }
173
173
  }
174
174
 
175
+ .activator {
176
+ display: inline-block;
177
+ }
178
+
175
179
  .contextButton {
176
180
  cursor: pointer;
177
181
  }
@@ -23,4 +23,8 @@ export default class AIcon extends Vue {
23
23
  .v-icon:not(.button)::after {
24
24
  background: none;
25
25
  }
26
+
27
+ .v-icon.button {
28
+ cursor: pointer;
29
+ }
26
30
  </style>
@@ -0,0 +1,226 @@
1
+ <template>
2
+ <div class="timePicker">
3
+ <div :class="['timeInput inputField', {focus: focusHour}]">
4
+ <div
5
+ class="up iconButton"
6
+ @click="hourUp"
7
+ >
8
+ <a-icon button>
9
+ $caretUpIcon
10
+ </a-icon>
11
+ </div>
12
+
13
+ <v-text-field
14
+ v-model="currentHour"
15
+ dense
16
+ outlined
17
+ hide-details
18
+ @wheel.prevent="onWheelHour"
19
+ @focus="focusHour = true"
20
+ @blur="updateHoursAndMinute"
21
+ />
22
+
23
+ <div
24
+ class="down iconButton"
25
+ @click="hourDown"
26
+ >
27
+ <a-icon button>
28
+ $caretDownIcon
29
+ </a-icon>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="hourMinutesSeparator">
34
+ :
35
+ </div>
36
+
37
+ <div :class="['timeInput inputField', {focus: focusMinute}]">
38
+ <div
39
+ class="up iconButton"
40
+ @click="minutesUp"
41
+ >
42
+ <a-icon button>
43
+ $caretUpIcon
44
+ </a-icon>
45
+ </div>
46
+
47
+ <v-text-field
48
+ v-model="currentMinutes"
49
+ dense
50
+ outlined
51
+ hide-details
52
+ @wheel.prevent="onWheelMinute"
53
+ @focus="focusMinute = true"
54
+ @blur="updateHoursAndMinute"
55
+ />
56
+
57
+ <div
58
+ class="down iconButton"
59
+ @click="minutesDown"
60
+ >
61
+ <a-icon button>
62
+ $caretDownIcon
63
+ </a-icon>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </template>
68
+
69
+ <script>
70
+ import { Component, Watch, Vue } from 'vue-property-decorator'
71
+ import moment from 'moment'
72
+ import formatHour from '@a-vue/utils/format-hour'
73
+ import formatMinutes from '@a-vue/utils/format-minutes'
74
+
75
+ @Component({
76
+ props: ['value']
77
+ })
78
+ export default class ATimePicker extends Vue {
79
+ currentDate = null
80
+ currentHour = null
81
+ currentMinutes = null
82
+
83
+ focusHour = false
84
+ focusMinute = false
85
+
86
+ created () {
87
+ this.currentDate = new Date(this.value)
88
+ this.initHourAndMinutes()
89
+ }
90
+
91
+ @Watch('value')
92
+ valueChanged () {
93
+ this.currentDate = new Date(this.value)
94
+ this.initHourAndMinutes()
95
+ }
96
+
97
+ onWheelHour (wheelEvent) {
98
+ if (!this.focusHour) {
99
+ return
100
+ }
101
+ if (wheelEvent.deltaY < 0) {
102
+ this.hourUp()
103
+ } else {
104
+ this.hourDown()
105
+ }
106
+ }
107
+
108
+ onWheelMinute (wheelEvent) {
109
+ if (!this.focusMinute) {
110
+ return
111
+ }
112
+ if (wheelEvent.deltaY < 0) {
113
+ this.minutesUp()
114
+ } else {
115
+ this.minutesDown()
116
+ }
117
+ }
118
+
119
+ get formattedHour () {
120
+ return formatHour(this.currentDate)
121
+ }
122
+
123
+ get formattedMinutes () {
124
+ return formatMinutes(this.currentDate)
125
+ }
126
+
127
+ get minutesValid () {
128
+ if (!this.currentMinutes) {
129
+ return true
130
+ }
131
+ if (!/^\d{1,2}$/.test(this.currentMinutes)) {
132
+ return false
133
+ }
134
+ return this.currentMinutes < 60
135
+ }
136
+
137
+ get hourValid () {
138
+ if (!this.currentHour) {
139
+ return true
140
+ }
141
+ if (!/^\d{1,2}$/.test(this.currentHour)) {
142
+ return false
143
+ }
144
+ return this.currentHour < 24
145
+ }
146
+
147
+ initHourAndMinutes () {
148
+ this.currentHour = this.formattedHour
149
+ this.currentMinutes = this.formattedMinutes
150
+ }
151
+
152
+ updateHoursAndMinute () {
153
+ if (this.hourValid) {
154
+ this.currentDate = moment(this.currentDate).hours(this.currentHour).toDate()
155
+ }
156
+
157
+ if (this.minutesValid) {
158
+ this.currentDate = moment(this.currentDate).minutes(this.currentMinutes).toDate()
159
+ }
160
+
161
+ this.focusMinute = false
162
+ this.focusHour = false
163
+
164
+ this.dispatchDate()
165
+ }
166
+
167
+ hourUp () {
168
+ this.currentDate = moment(this.currentDate).add(1, 'hours').toDate()
169
+ this.dispatchDate()
170
+ }
171
+
172
+ hourDown () {
173
+ this.currentDate = moment(this.currentDate).subtract(1, 'hours').toDate()
174
+ this.dispatchDate()
175
+ }
176
+
177
+ minutesUp () {
178
+ this.currentDate = moment(this.currentDate).add(15, 'minutes').toDate()
179
+ this.dispatchDate()
180
+ }
181
+
182
+ minutesDown () {
183
+ this.currentDate = moment(this.currentDate).subtract(15, 'minutes').toDate()
184
+ this.dispatchDate()
185
+ }
186
+
187
+ dispatchDate () {
188
+ this.initHourAndMinutes()
189
+ this.$emit('input', this.currentDate)
190
+ }
191
+ }
192
+ </script>
193
+
194
+ <style lang="scss" scoped>
195
+ .timePicker {
196
+ display: flex;
197
+ align-items: center;
198
+ text-align: center;
199
+
200
+ .timeInput {
201
+ line-height: 0;
202
+
203
+ > * {
204
+ text-align: center;
205
+ width: auto;
206
+ font-family: monospace;
207
+ }
208
+ }
209
+
210
+ .up {
211
+ margin-bottom: -1px;
212
+ }
213
+
214
+ .down {
215
+ margin-top: -3px;
216
+ }
217
+
218
+ .hourMinutesSeparator {
219
+ padding: 0 .4em;
220
+ }
221
+ }
222
+
223
+ .v-input ::v-deep(input) {
224
+ width: 20px;
225
+ }
226
+ </style>
@@ -1,22 +1,50 @@
1
1
  <template>
2
- <a-date-picker
3
- ref="datePicker"
4
- v-model="model[name]"
5
- :label="label || name"
6
- :validator="validator"
7
- v-bind="$attrs"
8
- v-on="$listeners"
9
- />
2
+ <div :class="{time}">
3
+ <a-date-picker
4
+ ref="datePicker"
5
+ v-model="model[name]"
6
+ :label="label || name"
7
+ :validator="validator"
8
+ v-bind="$attrs"
9
+ v-on="$listeners"
10
+ />
11
+
12
+ <a-time-picker
13
+ v-if="time"
14
+ ref="timePicker"
15
+ v-model="model[name]"
16
+ class="timePicker"
17
+ :label="label || name"
18
+ :validator="validator"
19
+ v-bind="$attrs"
20
+ v-on="$listeners"
21
+ />
22
+ </div>
10
23
  </template>
11
24
 
12
25
  <script>
13
26
  import { Component, Mixins } from '@a-vue'
14
27
  import { FormFieldMixin } from '../FormFieldMixin'
15
28
 
16
- @Component
29
+ @Component({
30
+ props: [{ time: false }]
31
+ })
17
32
  export default class FormFieldDate extends Mixins(FormFieldMixin) {
18
33
  validate () {
19
34
  this.$refs.datePicker.validate()
20
35
  }
21
36
  }
22
37
  </script>
38
+
39
+
40
+ <style lang="scss" scoped>
41
+ .time {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: .7rem;
45
+ }
46
+
47
+ .timePicker {
48
+ margin-top: -28px;
49
+ }
50
+ </style>
@@ -0,0 +1,16 @@
1
+ import moment from 'moment'
2
+
3
+ export default function (date) {
4
+ function addZero (i) {
5
+ if (i < 10) {
6
+ i = '0' + i
7
+ }
8
+ return i
9
+ }
10
+
11
+ if (!moment(date).isValid()) {
12
+ return 'Invalid Date'
13
+ }
14
+
15
+ return addZero(date.getHours())
16
+ }
@@ -0,0 +1,16 @@
1
+ import moment from 'moment'
2
+
3
+ export default function (date) {
4
+ function addZero (i) {
5
+ if (i < 10) {
6
+ i = '0' + i
7
+ }
8
+ return i
9
+ }
10
+
11
+ if (!moment(date).isValid()) {
12
+ return 'Invalid Date'
13
+ }
14
+
15
+ return addZero(date.getMinutes())
16
+ }