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
14
+ :checked="extraSettings?.dateRange"
15
+ @update:checked="onDateRangeChange">
16
+ {{ t('forms', 'Query date range') }}
17
+ </NcActionCheckbox>
18
+ <NcActionInput
19
+ v-model="dateMin"
20
+ type="date"
21
+ :label="t('forms', 'Pick minimum date')"
22
+ hide-label
23
+ :formatter="extraSettingsFormatter"
24
+ is-native-picker
25
+ :max="dateMax">
26
+ <template #icon>
27
+ <Pencil :size="20" />
28
+ </template>
29
+ </NcActionInput>
30
+ <NcActionInput
31
+ v-model="dateMax"
32
+ type="date"
33
+ :label="t('forms', 'Pick maximum date')"
34
+ hide-label
35
+ :formatter="extraSettingsFormatter"
36
+ is-native-picker
37
+ :min="dateMin">
38
+ <template #icon>
39
+ <Pencil :size="20" />
40
+ </template>
41
+ </NcActionInput>
42
+ </template>
12
43
<div class="question__content">
13
44
<NcDateTimePicker
14
45
:value="time"
17
48
:placeholder="datetimePickerPlaceholder"
18
49
:show-second="false"
19
50
:type="answerType.pickerType"
51
+ :disabled-date="disabledDates"
20
52
:input-attr="inputAttr"
53
+ :range="extraSettings?.dateRange"
54
+ range-separator=" - "
21
55
@change="onValueChange" />
22
56
</div>
23
57
</Question>
24
58
</template>
25
59
26
60
<script>
27
61
import moment from '@nextcloud/moment'
28
-
29
62
import QuestionMixin from '../../mixins/QuestionMixin.js'
63
+ import NcActionCheckbox from '@nextcloud/vue/components/NcActionCheckbox'
64
+ import NcActionInput from '@nextcloud/vue/components/NcActionInput'
30
65
import NcDateTimePicker from '@nextcloud/vue/components/NcDateTimePicker'
66
+ import Pencil from 'vue-material-design-icons/Pencil.vue'
31
67
32
68
export default {
33
69
name: 'QuestionDate',
34
70
35
71
components: {
72
+ NcActionCheckbox,
73
+ NcActionInput,
36
74
NcDateTimePicker,
75
+ Pencil,
37
76
},
38
77
39
78
mixins: [QuestionMixin],
@@ -44,15 +83,23 @@ export default {
44
83
stringify: this.stringify,
45
84
parse: this.parse,
46
85
},
86
+ extraSettingsFormatter: {
87
+ stringify: this.stringifyDate,
88
+ parse: this.parseTimestampToDate,
89
+ },
47
90
}
48
91
},
49
92
50
93
computed: {
51
94
datetimePickerPlaceholder() {
52
95
if (this.readOnly) {
53
- return this.answerType.submitPlaceholder
96
+ return this.question.extraSettings?.dateRange
97
+ ? this.answerType.submitPlaceholderRange
98
+ : this.answerType.submitPlaceholder
54
99
}
55
- return this.answerType.createPlaceholder
100
+ return this.question.extraSettings?.dateRange
101
+ ? this.answerType.createPlaceholderRange
102
+ : this.answerType.createPlaceholder
56
103
},
57
104
58
105
/**
@@ -68,8 +115,45 @@ export default {
68
115
},
69
116
70
117
time() {
118
+ if (this.extraSettings?.dateRange) {
119
+ return this.values
120
+ ? [this.parse(this.values[0]), this.parse(this.values[1])]
121
+ : null
122
+ }
71
123
return this.values ? this.parse(this.values[0]) : null
72
124
},
125
+
126
+ /**
127
+ * The maximum allowable date for the date input field
128
+ */
129
+ dateMax: {
130
+ get() {
131
+ return this.extraSettings?.dateMax
132
+ ? moment(this.extraSettings.dateMax, 'X').toDate()
133
+ : null
134
+ },
135
+ set(value) {
136
+ this.onExtraSettingsChange({
137
+ dateMax: parseInt(moment(value).format('X')),
138
+ })
139
+ },
140
+ },
141
+
142
+ /**
143
+ * The minimum allowable date for the date input field
144
+ */
145
+ dateMin: {
146
+ get() {
147
+ return this.extraSettings?.dateMin
148
+ ? moment(this.extraSettings.dateMin, 'X').toDate()
149
+ : null
150
+ },
151
+ set(value) {
152
+ this.onExtraSettingsChange({
153
+ dateMin: parseInt(moment(value).format('X')),
154
+ })
155
+ },
156
+ },
73
157
},
74
158
75
159
methods: {
@@ -99,12 +183,63 @@ export default {
99
183
/**
100
184
* Store Value
101
185
*
102
- * @param {Date} date The date to store
186
+ * @param {Date|Array<Date> } date The date or date range to store
103
187
*/
104
188
onValueChange(date) {
105
- this.$emit('update:values', [
106
- moment(date).format(this.answerType.storageFormat),
107
- ])
189
+ if (this.extraSettings?.dateRange) {
190
+ this.$emit('update:values', [
191
+ moment(date[0]).format(this.answerType.storageFormat),
192
+ moment(date[1]).format(this.answerType.storageFormat),
193
+ ])
194
+ } else {
195
+ this.$emit('update:values', [
196
+ moment(date).format(this.answerType.storageFormat),
197
+ ])
198
+ }
199
+ },
200
+
201
+ /**
202
+ * Handles the change event for the date range setting.
203
+ *
204
+ * @param {boolean} checked - Indicates whether the date range option is enabled (true) or disabled (false).
205
+ * Updates the extra settings with the date range value. If `checked` is true, the date range is set;
206
+ * otherwise, it is set to null.
207
+ */
208
+ onDateRangeChange(checked) {
209
+ this.onExtraSettingsChange({ dateRange: checked === true ?? null })
210
+ },
211
+
212
+ /**
213
+ * Determines if a given date should be disabled.
214
+ *
215
+ * @param {Date} date - The date to check.
216
+ * @return {boolean} - Returns true if the date should be disabled, otherwise false.
217
+ */
218
+ disabledDates(date) {
219
+ return (
220
+ (this.dateMin && date < this.dateMin) ||
221
+ (this.dateMax && date > this.dateMax)
222
+ )
223
+ },
224
+
225
+ /**
226
+ * Datepicker timestamp to string
227
+ *
228
+ * @param {Date} datetime the datepicker Date
229
+ * @return {string}
230
+ */
231
+ stringifyDate(datetime) {
232
+ return moment(datetime).format('L')
233
+ },
234
+
235
+ /**
236
+ * Form expires timestamp to Date of the datepicker
237
+ *
238
+ * @param {number} value the expires timestamp
239
+ * @return {Date}
240
+ */
241
+ parseTimestampToDate(value) {
242
+ return moment(value, 'X').toDate()
108
243
},
109
244
},
110
245
}
0 commit comments