9
9
:title-placeholder="answerType.titlePlaceholder"
10
10
:warning-invalid="answerType.warningInvalid"
11
11
v-on="commonListeners">
12
+ <template v-if="answerType.pickerType === 'date'" #actions>
13
+ <NcActionCheckbox v-model="dateRange">
14
+ {{ t('forms', 'Use date range') }}
15
+ </NcActionCheckbox>
16
+ <NcActionInput
17
+ v-model="dateMin"
18
+ type="date"
19
+ :label="t('forms', 'Earliest date')"
20
+ hide-label
21
+ :formatter="extraSettingsFormatter"
22
+ is-native-picker
23
+ :max="dateMax">
24
+ <template #icon>
25
+ <NcIconSvgWrapper
26
+ :svg="svgTodayIcon"
27
+ :name="t('forms', 'Earliest date')" />
28
+ </template>
29
+ </NcActionInput>
30
+ <NcActionInput
31
+ v-model="dateMax"
32
+ type="date"
33
+ :label="t('forms', 'Latest date')"
34
+ hide-label
35
+ :formatter="extraSettingsFormatter"
36
+ is-native-picker
37
+ :min="dateMin">
38
+ <template #icon>
39
+ <NcIconSvgWrapper
40
+ :svg="svgEventIcon"
41
+ :name="t('forms', 'Latest date')" />
42
+ </template>
43
+ </NcActionInput>
44
+ </template>
12
45
<div class="question__content">
13
46
<NcDateTimePicker
14
47
:value="time"
17
50
:placeholder="datetimePickerPlaceholder"
18
51
:show-second="false"
19
52
:type="answerType.pickerType"
53
+ :disabled-date="disabledDates"
20
54
:input-attr="inputAttr"
55
+ :range="extraSettings?.dateRange"
56
+ range-separator=" - "
21
57
@change="onValueChange" />
22
58
</div>
23
59
</Question>
24
60
</template>
25
61
26
62
<script>
27
- import moment from '@nextcloud/moment'
63
+ import svgEventIcon from '../../../img/event.svg?raw'
64
+ import svgTodayIcon from '../../../img/today.svg?raw'
28
65
29
- import QuestionMixin from '../../mixins/QuestionMixin.js'
66
+ import moment from '@nextcloud/moment'
67
+ import NcActionCheckbox from '@nextcloud/vue/components/NcActionCheckbox'
68
+ import NcActionInput from '@nextcloud/vue/components/NcActionInput'
30
69
import NcDateTimePicker from '@nextcloud/vue/components/NcDateTimePicker'
70
+ import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
71
+ import QuestionMixin from '../../mixins/QuestionMixin.js'
31
72
32
73
export default {
33
74
name: 'QuestionDate',
34
75
35
76
components: {
77
+ NcActionCheckbox,
78
+ NcActionInput,
36
79
NcDateTimePicker,
80
+ NcIconSvgWrapper,
37
81
},
38
82
39
83
mixins: [QuestionMixin],
@@ -44,15 +88,25 @@ export default {
44
88
stringify: this.stringify,
45
89
parse: this.parse,
46
90
},
91
+ extraSettingsFormatter: {
92
+ stringify: this.stringifyDate,
93
+ parse: this.parseTimestampToDate,
94
+ },
95
+ svgEventIcon,
96
+ svgTodayIcon,
47
97
}
48
98
},
49
99
50
100
computed: {
51
101
datetimePickerPlaceholder() {
52
102
if (this.readOnly) {
53
- return this.answerType.submitPlaceholder
103
+ return this.extraSettings?.dateRange
104
+ ? this.answerType.submitPlaceholderRange
105
+ : this.answerType.submitPlaceholder
54
106
}
55
- return this.answerType.createPlaceholder
107
+ return this.extraSettings?.dateRange
108
+ ? this.answerType.createPlaceholderRange
109
+ : this.answerType.createPlaceholder
56
110
},
57
111
58
112
/**
@@ -68,8 +122,54 @@ export default {
68
122
},
69
123
70
124
time() {
125
+ if (this.extraSettings?.dateRange) {
126
+ return this.values
127
+ ? [this.parse(this.values[0]), this.parse(this.values[1])]
128
+ : null
129
+ }
71
130
return this.values ? this.parse(this.values[0]) : null
72
131
},
132
+
133
+ /**
134
+ * The maximum allowable date for the date input field
135
+ */
136
+ dateMax: {
137
+ get() {
138
+ return this.extraSettings?.dateMax
139
+ ? moment(this.extraSettings.dateMax, 'X').toDate()
140
+ : null
141
+ },
142
+ set(value) {
143
+ this.onExtraSettingsChange({
144
+ dateMax: parseInt(moment(value).format('X')),
145
+ })
146
+ },
147
+ },
148
+
149
+ /**
150
+ * The minimum allowable date for the date input field
151
+ */
152
+ dateMin: {
153
+ get() {
154
+ return this.extraSettings?.dateMin
155
+ ? moment(this.extraSettings.dateMin, 'X').toDate()
156
+ : null
157
+ },
158
+ set(value) {
159
+ this.onExtraSettingsChange({
160
+ dateMin: parseInt(moment(value).format('X')),
161
+ })
162
+ },
163
+ },
164
+
165
+ dateRange: {
166
+ get() {
167
+ return this.extraSettings?.dateRange ?? false
168
+ },
169
+ set(value) {
170
+ this.onExtraSettingsChange({ dateRange: value === true ?? null })
171
+ },
172
+ },
73
173
},
74
174
75
175
methods: {
@@ -99,12 +199,52 @@ export default {
99
199
/**
100
200
* Store Value
101
201
*
102
- * @param {Date} date The date to store
202
+ * @param {Date|Array<Date> } date The date or date range to store
103
203
*/
104
204
onValueChange(date) {
105
- this.$emit('update:values', [
106
- moment(date).format(this.answerType.storageFormat),
107
- ])
205
+ if (this.extraSettings?.dateRange) {
206
+ this.$emit('update:values', [
207
+ moment(date[0]).format(this.answerType.storageFormat),
208
+ moment(date[1]).format(this.answerType.storageFormat),
209
+ ])
210
+ } else {
211
+ this.$emit('update:values', [
212
+ moment(date).format(this.answerType.storageFormat),
213
+ ])
214
+ }
215
+ },
216
+
217
+ /**
218
+ * Determines if a given date should be disabled.
219
+ *
220
+ * @param {Date} date - The date to check.
221
+ * @return {boolean} - Returns true if the date should be disabled, otherwise false.
222
+ */
223
+ disabledDates(date) {
224
+ return (
225
+ (this.dateMin && date < this.dateMin) ||
226
+ (this.dateMax && date > this.dateMax)
227
+ )
228
+ },
229
+
230
+ /**
231
+ * Datepicker timestamp to string
232
+ *
233
+ * @param {Date} datetime the datepicker Date
234
+ * @return {string}
235
+ */
236
+ stringifyDate(datetime) {
237
+ return moment(datetime).format('L')
238
+ },
239
+
240
+ /**
241
+ * Form expires timestamp to Date of the datepicker
242
+ *
243
+ * @param {number} value the expires timestamp
244
+ * @return {Date}
245
+ */
246
+ parseTimestampToDate(value) {
247
+ return moment(value, 'X').toDate()
108
248
},
109
249
},
110
250
}
0 commit comments