99 :title-placeholder =" answerType.titlePlaceholder"
1010 :warning-invalid =" answerType.warningInvalid"
1111 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 >
1245 <div class =" question__content" >
1346 <NcDateTimePicker
1447 :value =" time"
1750 :placeholder =" datetimePickerPlaceholder"
1851 :show-second =" false"
1952 :type =" answerType.pickerType"
53+ :disabled-date =" disabledDates"
2054 :input-attr =" inputAttr"
55+ :range =" extraSettings?.dateRange"
56+ range-separator =" - "
2157 @change =" onValueChange" />
2258 </div >
2359 </Question >
2460</template >
2561
2662<script >
27- import moment from ' @nextcloud/moment'
63+ import svgEventIcon from ' ../../../img/event.svg?raw'
64+ import svgTodayIcon from ' ../../../img/today.svg?raw'
2865
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'
3069import NcDateTimePicker from ' @nextcloud/vue/components/NcDateTimePicker'
70+ import NcIconSvgWrapper from ' @nextcloud/vue/components/NcIconSvgWrapper'
71+ import QuestionMixin from ' ../../mixins/QuestionMixin.js'
3172
3273export default {
3374 name: ' QuestionDate' ,
3475
3576 components: {
77+ NcActionCheckbox,
78+ NcActionInput,
3679 NcDateTimePicker,
80+ NcIconSvgWrapper,
3781 },
3882
3983 mixins: [QuestionMixin],
@@ -44,15 +88,25 @@ export default {
4488 stringify: this .stringify ,
4589 parse: this .parse ,
4690 },
91+ extraSettingsFormatter: {
92+ stringify: this .stringifyDate ,
93+ parse: this .parseTimestampToDate ,
94+ },
95+ svgEventIcon,
96+ svgTodayIcon,
4797 }
4898 },
4999
50100 computed: {
51101 datetimePickerPlaceholder () {
52102 if (this .readOnly ) {
53- return this .answerType .submitPlaceholder
103+ return this .extraSettings ? .dateRange
104+ ? this .answerType .submitPlaceholderRange
105+ : this .answerType .submitPlaceholder
54106 }
55- return this .answerType .createPlaceholder
107+ return this .extraSettings ? .dateRange
108+ ? this .answerType .createPlaceholderRange
109+ : this .answerType .createPlaceholder
56110 },
57111
58112 /**
@@ -68,8 +122,54 @@ export default {
68122 },
69123
70124 time () {
125+ if (this .extraSettings ? .dateRange ) {
126+ return this .values
127+ ? [this .parse (this .values [0 ]), this .parse (this .values [1 ])]
128+ : null
129+ }
71130 return this .values ? this .parse (this .values [0 ]) : null
72131 },
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+ },
73173 },
74174
75175 methods: {
@@ -99,12 +199,52 @@ export default {
99199 /**
100200 * Store Value
101201 *
102- * @param {Date} date The date to store
202+ * @param {Date|Array<Date> } date The date or date range to store
103203 */
104204 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 ()
108248 },
109249 },
110250}
0 commit comments