fix(task-modal): fixed calendar position after first click on month switch

This commit is contained in:
Matej Glasnák committed 2025-09-12 10:42:14 +02:00
1 parent c1ead219e6
commit f38d45160c
4 files changed
+108 -72

No files matched your search

+4 -4
View File
@@ -180,7 +180,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n // Mixin to fix autofocus on v-input in modals where date selects are used\n data() {\n return {\n preventInputFocus: false\n };\n },\n methods: {\n setFocusEvent() {\n document.querySelectorAll('.v-autocomplete input').forEach(input => {\n input.addEventListener('focus', this.onInputFocus);\n });\n },\n onDateFocus($event) {\n if ($event == undefined) {\n this.preventInputFocus = true;\n }\n },\n onInputFocus($event) {\n if (this.preventInputFocus) {\n $event.target.blur();\n this.preventInputFocus = false;\n }\n }\n }\n});\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/_mixins/vuetify-fix-focus.ts?"); eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n // Mixin to fix autofocus on v-input in modals where date selects are used\n data() {\n return {\n preventInputFocus: false\n };\n },\n methods: {\n setFocusEvent() {\n document.querySelectorAll('.v-autocomplete input').forEach(input => {\n input.addEventListener('focus', this.onInputFocus);\n });\n },\n onDateFocus($event) {\n if ($event == undefined) {\n this.preventInputFocus = true;\n }\n },\n onDateOpen($event) {\n if ($event == undefined) {\n this.preventInputFocus = true;\n }\n },\n onInputFocus($event) {\n setTimeout(() => {\n if (this.preventInputFocus) {\n $event.target.blur();\n this.preventInputFocus = false;\n }\n }, 100);\n }\n }\n});\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/_mixins/vuetify-fix-focus.ts?");
/***/ }), /***/ }),
@@ -807,7 +807,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _vuelidate_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vuelidate/core */ \"./node_modules/@vuelidate/core/dist/index.esm.js\");\n/* harmony import */ var _vuelidate_validators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @vuelidate/validators */ \"./node_modules/@vuelidate/validators/dist/index.esm.js\");\n/* harmony import */ var _vuepic_vue_datepicker__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vuepic/vue-datepicker */ \"./node_modules/@vuepic/vue-datepicker/dist/vue-datepicker.js\");\n/* harmony import */ var _plugins_tm_modal_mixins_vuetify_fix_focus__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/plugins/tm@modal/_mixins/vuetify-fix-focus */ \"./src/plugins/tm@modal/_mixins/vuetify-fix-focus.ts\");\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n mixins: [_plugins_tm_modal_mixins_vuetify_fix_focus__WEBPACK_IMPORTED_MODULE_2__[\"default\"]],\n components: {\n Datepicker: _vuepic_vue_datepicker__WEBPACK_IMPORTED_MODULE_1__[\"default\"]\n },\n props: {\n timeblock: {\n type: Object,\n required: true\n },\n deletable: {\n type: Boolean,\n default: false\n },\n editable: {\n type: Boolean,\n default: false\n }\n },\n data() {\n return {\n v$: (0,_vuelidate_core__WEBPACK_IMPORTED_MODULE_0__[\"default\"])()\n };\n },\n validations() {\n return {\n timeblock: {\n starts_at_time: {\n required: (0,_vuelidate_validators__WEBPACK_IMPORTED_MODULE_3__.requiredIf)(this.timeblock.date)\n },\n ends_at_time: {\n required: (0,_vuelidate_validators__WEBPACK_IMPORTED_MODULE_3__.requiredIf)(this.timeblock.date)\n }\n }\n };\n },\n methods: {\n async openDatepicker(ref) {\n this.$refs[ref].openMenu();\n this.$nextTick(() => {\n this.$refs['datepicker-wrapper'].scrollIntoView({\n behavior: 'instant',\n block: 'center',\n inline: 'center'\n });\n this.$nextTick(() => {\n const popup = document.querySelector('.dp__menu.dp__menu_index');\n const isBottom = popup.querySelector('.dp__arrow_bottom');\n const yDifference = isBottom ? 0 - popup.clientHeight - 42 : 35;\n popup.style.top = window.innerHeight / 2 + yDifference + 'px';\n });\n });\n },\n updateDate(date) {\n const timeblock = {\n ...this.timeblock\n };\n if (date) timeblock.date = date;\n this.$emit('updateTimeblock', timeblock);\n },\n updateStartTime(event) {\n const timeblock = {\n ...this.timeblock\n };\n timeblock.starts_at_time = event.target.value;\n this.$emit('updateTimeblock', timeblock);\n },\n updateEndTime(event) {\n const timeblock = {\n ...this.timeblock\n };\n timeblock.ends_at_time = event.target.value;\n this.$emit('updateTimeblock', timeblock);\n }\n }\n});\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/task/_components/a-timeblock.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D"); eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _vuelidate_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vuelidate/core */ \"./node_modules/@vuelidate/core/dist/index.esm.js\");\n/* harmony import */ var _vuelidate_validators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @vuelidate/validators */ \"./node_modules/@vuelidate/validators/dist/index.esm.js\");\n/* harmony import */ var _vuepic_vue_datepicker__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vuepic/vue-datepicker */ \"./node_modules/@vuepic/vue-datepicker/dist/vue-datepicker.js\");\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n components: {\n Datepicker: _vuepic_vue_datepicker__WEBPACK_IMPORTED_MODULE_1__[\"default\"]\n },\n props: {\n timeblock: {\n type: Object,\n required: true\n },\n deletable: {\n type: Boolean,\n default: false\n },\n editable: {\n type: Boolean,\n default: false\n },\n preventInputFocus: {\n type: Boolean,\n default: false\n },\n onInputFocus: {\n type: Function,\n default: () => ({})\n },\n onDateOpen: {\n type: Function,\n default: () => ({})\n }\n },\n data() {\n return {\n v$: (0,_vuelidate_core__WEBPACK_IMPORTED_MODULE_0__[\"default\"])()\n };\n },\n validations() {\n return {\n timeblock: {\n starts_at_time: {\n required: (0,_vuelidate_validators__WEBPACK_IMPORTED_MODULE_2__.requiredIf)(this.timeblock.date)\n },\n ends_at_time: {\n required: (0,_vuelidate_validators__WEBPACK_IMPORTED_MODULE_2__.requiredIf)(this.timeblock.date)\n }\n }\n };\n },\n methods: {\n async openDatepicker(ref) {\n this.$refs[ref].openMenu();\n },\n updateDate(date) {\n const timeblock = {\n ...this.timeblock\n };\n if (date) timeblock.date = date;\n this.$emit('updateTimeblock', timeblock);\n },\n updateStartTime(event) {\n const timeblock = {\n ...this.timeblock\n };\n timeblock.starts_at_time = event.target.value;\n this.$emit('updateTimeblock', timeblock);\n },\n updateEndTime(event) {\n const timeblock = {\n ...this.timeblock\n };\n timeblock.ends_at_time = event.target.value;\n this.$emit('updateTimeblock', timeblock);\n }\n }\n});\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/task/_components/a-timeblock.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
/***/ }), /***/ }),
@@ -2977,7 +2977,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuetify/lib/components/VTextField/index.mjs */ \"./node_modules/vuetify/lib/components/VTextField/VTextField.mjs\");\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_0__.pushScopeId)(\"data-v-da2562be\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"timeblock w-100\"\n};\nconst _hoisted_2 = {\n key: 0,\n class: \"x-button\"\n};\nconst _hoisted_3 = {\n class: \"splitted-time-inputs\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_Datepicker = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"Datepicker\");\n \n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [$props.deletable && $props.editable ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('removeTimeblock')),\n class: \"x-button\"\n }, \"x\")])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n onClick: _cache[1] || (_cache[1] = $event => $options.openDatepicker('datepicker')),\n class: \"datepicker-wrapper\",\n ref: \"datepicker-wrapper\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Datepicker, {\n \"model-value\": $props.timeblock.date,\n ref: \"datepicker\",\n onFocus: _ctx.onDateFocus,\n \"onUpdate:modelValue\": $options.updateDate,\n format: \"dd.MM.yyyy\",\n locale: \"sk\",\n \"select-text\": \"Vybrať\",\n \"cancel-text\": \"Zrušiť\",\n placeholder: \"Dátum\",\n \"auto-apply\": true,\n \"enable-time-picker\": false,\n class: \"mb-5 modal-input datepicker-input\"\n }, null, 8 /* PROPS */, [\"model-value\", \"onFocus\", \"onUpdate:modelValue\"])], 512 /* NEED_PATCH */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__.VTextField, {\n value: $props.timeblock.starts_at_time,\n onInput: $options.updateStartTime,\n onFocus: _ctx.onInputFocus,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n error: $data.v$?.timeblock.starts_at_time.$errors.length\n }),\n type: \"time\",\n variant: \"solo\",\n \"bg-color\": \"white\",\n label: \"Začiatok\"\n }, null, 8 /* PROPS */, [\"value\", \"onInput\", \"onFocus\", \"class\"]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__.VTextField, {\n value: $props.timeblock.ends_at_time,\n onInput: $options.updateEndTime,\n onFocus: _ctx.onInputFocus,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n error: $data.v$?.timeblock.ends_at_time.$errors.length\n }),\n type: \"time\",\n variant: \"solo\",\n \"bg-color\": \"white\",\n label: \"Koniec\"\n }, null, 8 /* PROPS */, [\"value\", \"onInput\", \"onFocus\", \"class\"])])]);\n}\n\n/* Vuetify */\n\n\n\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/task/_components/a-timeblock.vue?./node_modules/webpack-plugin-vuetify/dist/scriptLoader.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B5%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D"); eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuetify/lib/components/VTextField/index.mjs */ \"./node_modules/vuetify/lib/components/VTextField/VTextField.mjs\");\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_0__.pushScopeId)(\"data-v-da2562be\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"timeblock w-100\"\n};\nconst _hoisted_2 = {\n key: 0,\n class: \"x-button\"\n};\nconst _hoisted_3 = {\n class: \"splitted-time-inputs\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_Datepicker = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)(\"Datepicker\");\n \n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_1, [$props.deletable && $props.editable ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n onClick: _cache[0] || (_cache[0] = $event => _ctx.$emit('removeTimeblock')),\n class: \"x-button\"\n }, \"x\")])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", {\n onClick: _cache[1] || (_cache[1] = $event => $options.openDatepicker('datepicker')),\n class: \"datepicker-wrapper\",\n ref: \"datepicker-wrapper\"\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Datepicker, {\n \"model-value\": $props.timeblock.date,\n ref: \"datepicker\",\n onOpen: $props.onDateOpen,\n \"onUpdate:modelValue\": $options.updateDate,\n format: \"dd.MM.yyyy\",\n locale: \"sk\",\n \"select-text\": \"Vybrať\",\n \"cancel-text\": \"Zrušiť\",\n placeholder: \"Dátum\",\n \"auto-apply\": true,\n \"enable-time-picker\": false,\n class: \"mb-5 modal-input datepicker-input\"\n }, null, 8 /* PROPS */, [\"model-value\", \"onOpen\", \"onUpdate:modelValue\"])], 512 /* NEED_PATCH */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"div\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__.VTextField, {\n value: $props.timeblock.starts_at_time,\n onInput: $options.updateStartTime,\n onFocus: $props.onInputFocus,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n error: $data.v$?.timeblock.starts_at_time.$errors.length\n }),\n type: \"time\",\n variant: \"solo\",\n \"bg-color\": \"white\",\n label: \"Začiatok\"\n }, null, 8 /* PROPS */, [\"value\", \"onInput\", \"onFocus\", \"class\"]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_1__.VTextField, {\n value: $props.timeblock.ends_at_time,\n onInput: $options.updateEndTime,\n onFocus: $props.onInputFocus,\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({\n error: $data.v$?.timeblock.ends_at_time.$errors.length\n }),\n type: \"time\",\n variant: \"solo\",\n \"bg-color\": \"white\",\n label: \"Koniec\"\n }, null, 8 /* PROPS */, [\"value\", \"onInput\", \"onFocus\", \"class\"])])]);\n}\n\n/* Vuetify */\n\n\n\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@modal/task/_components/a-timeblock.vue?./node_modules/webpack-plugin-vuetify/dist/scriptLoader.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B5%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
/***/ }), /***/ }),
@@ -3043,7 +3043,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var vuetify_lib_components_VAutocomplete_index_mjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! vuetify/lib/components/VAutocomplete/index.mjs */ \"./node_modules/vuetify/lib/components/VAutocomplete/VAutocomplete.mjs\");\n/* harmony import */ var vuetify_lib_components_VBtn_index_mjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! vuetify/lib/components/VBtn/index.mjs */ \"./node_modules/vuetify/lib/components/VBtn/VBtn.mjs\");\n/* harmony import */ var vuetify_lib_components_VCard_index_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vuetify/lib/components/VCard/index.mjs */ \"./node_modules/vuetify/lib/components/VCard/VCard.mjs\");\n/* harmony import */ var vuetify_lib_components_VCard_index_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vuetify/lib/components/VCard/index.mjs */ \"./node_modules/vuetify/lib/components/VCard/VCardActions.mjs\");\n/* harmony import */ var vuetify_lib_components_VDialog_index_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vuetify/lib/components/VDialog/index.mjs */ \"./node_modules/vuetify/lib/components/VDialog/VDialog.mjs\");\n/* harmony import */ var vuetify_lib_components_VIcon_index_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! vuetify/lib/components/VIcon/index.mjs */ \"./node_modules/vuetify/lib/components/VIcon/VIcon.mjs\");\n/* harmony import */ var vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! vuetify/lib/components/VTextField/index.mjs */ \"./node_modules/vuetify/lib/components/VTextField/VTextField.mjs\");\n\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_1__.pushScopeId)(\"data-v-1c35a9a1\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"d-flex justify-space-between align-center modal-header\"\n};\nconst _hoisted_2 = {\n class: \"splitted-inputs\"\n};\nconst _hoisted_3 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M23.057 7.057l-16 16c-0.52 0.52-0.52 1.365 0 1.885s1.365 0.52 1.885 0l16-16c0.52-0.52 0.52-1.365 0-1.885s-1.365-0.52-1.885 0z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_4 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M7.057 8.943l16 16c0.52 0.52 1.365 0.52 1.885 0s0.52-1.365 0-1.885l-16-16c-0.52-0.52-1.365-0.52-1.885 0s-0.52 1.365 0 1.885z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_5 = [_hoisted_3, _hoisted_4];\nconst _hoisted_6 = [\"onClick\"];\nconst _hoisted_7 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M23.057 7.057l-16 16c-0.52 0.52-0.52 1.365 0 1.885s1.365 0.52 1.885 0l16-16c0.52-0.52 0.52-1.365 0-1.885s-1.365-0.52-1.885 0z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_8 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M7.057 8.943l16 16c0.52 0.52 1.365 0.52 1.885 0s0.52-1.365 0-1.885l-16-16c-0.52-0.52-1.365-0.52-1.885 0s-0.52 1.365 0 1.885z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_9 = [_hoisted_7, _hoisted_8];\nconst _hoisted_10 = {\n key: 2,\n class: \"timeblocks w-100\"\n};\nconst _hoisted_11 = {\n class: \"end-button w-100\"\n};\nconst _hoisted_12 = {\n class: \"splitted-time-inputs w-100\"\n};\nconst _hoisted_13 = {\n class: \"w-100 modal-input\"\n};\nconst _hoisted_14 = {\n class: \"d-flex justify-space-between align-center\"\n};\nconst _hoisted_15 = {\n class: \"d-flex justify-space-between align-center modal-header border-bottom pb-4\"\n};\nconst _hoisted_16 = {\n class: \"d-flex justify-start\"\n};\nconst _hoisted_17 = [\"src\"];\nconst _hoisted_18 = [\"src\"];\nconst _hoisted_19 = {\n class: \"w-100\"\n};\nconst _hoisted_20 = {\n class: \"d-flex justify-start align-center mt-8\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n \n \n Line truncated eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var vuetify_lib_components_VAutocomplete_index_mjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! vuetify/lib/components/VAutocomplete/index.mjs */ \"./node_modules/vuetify/lib/components/VAutocomplete/VAutocomplete.mjs\");\n/* harmony import */ var vuetify_lib_components_VBtn_index_mjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! vuetify/lib/components/VBtn/index.mjs */ \"./node_modules/vuetify/lib/components/VBtn/VBtn.mjs\");\n/* harmony import */ var vuetify_lib_components_VCard_index_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vuetify/lib/components/VCard/index.mjs */ \"./node_modules/vuetify/lib/components/VCard/VCard.mjs\");\n/* harmony import */ var vuetify_lib_components_VCard_index_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! vuetify/lib/components/VCard/index.mjs */ \"./node_modules/vuetify/lib/components/VCard/VCardActions.mjs\");\n/* harmony import */ var vuetify_lib_components_VDialog_index_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vuetify/lib/components/VDialog/index.mjs */ \"./node_modules/vuetify/lib/components/VDialog/VDialog.mjs\");\n/* harmony import */ var vuetify_lib_components_VIcon_index_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! vuetify/lib/components/VIcon/index.mjs */ \"./node_modules/vuetify/lib/components/VIcon/VIcon.mjs\");\n/* harmony import */ var vuetify_lib_components_VTextField_index_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! vuetify/lib/components/VTextField/index.mjs */ \"./node_modules/vuetify/lib/components/VTextField/VTextField.mjs\");\n\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_1__.pushScopeId)(\"data-v-1c35a9a1\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_1__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"d-flex justify-space-between align-center modal-header\"\n};\nconst _hoisted_2 = {\n class: \"splitted-inputs\"\n};\nconst _hoisted_3 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M23.057 7.057l-16 16c-0.52 0.52-0.52 1.365 0 1.885s1.365 0.52 1.885 0l16-16c0.52-0.52 0.52-1.365 0-1.885s-1.365-0.52-1.885 0z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_4 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M7.057 8.943l16 16c0.52 0.52 1.365 0.52 1.885 0s0.52-1.365 0-1.885l-16-16c-0.52-0.52-1.365-0.52-1.885 0s-0.52 1.365 0 1.885z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_5 = [_hoisted_3, _hoisted_4];\nconst _hoisted_6 = [\"onClick\"];\nconst _hoisted_7 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M23.057 7.057l-16 16c-0.52 0.52-0.52 1.365 0 1.885s1.365 0.52 1.885 0l16-16c0.52-0.52 0.52-1.365 0-1.885s-1.365-0.52-1.885 0z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_8 = /*#__PURE__*/_withScopeId(() => /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_1__.createElementVNode)(\"path\", {\n d: \"M7.057 8.943l16 16c0.52 0.52 1.365 0.52 1.885 0s0.52-1.365 0-1.885l-16-16c-0.52-0.52-1.365-0.52-1.885 0s-0.52 1.365 0 1.885z\"\n}, null, -1 /* HOISTED */));\nconst _hoisted_9 = [_hoisted_7, _hoisted_8];\nconst _hoisted_10 = {\n key: 2,\n class: \"timeblocks w-100\"\n};\nconst _hoisted_11 = {\n class: \"end-button w-100\"\n};\nconst _hoisted_12 = {\n class: \"splitted-time-inputs w-100\"\n};\nconst _hoisted_13 = {\n class: \"w-100 modal-input\"\n};\nconst _hoisted_14 = {\n class: \"d-flex justify-space-between align-center\"\n};\nconst _hoisted_15 = {\n class: \"d-flex justify-space-between align-center modal-header border-bottom pb-4\"\n};\nconst _hoisted_16 = {\n class: \"d-flex justify-start\"\n};\nconst _hoisted_17 = [\"src\"];\nconst _hoisted_18 = [\"src\"];\nconst _hoisted_19 = {\n class: \"w-100\"\n};\nconst _hoisted_20 = {\n class: \"d-flex justify-start align-center mt-8\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n \n \n Line truncated
/***/ }), /***/ }),
@@ -2,28 +2,36 @@ export default {
// Mixin to fix autofocus on v-input in modals where date selects are used // Mixin to fix autofocus on v-input in modals where date selects are used
data() { data() {
return { return {
preventInputFocus: false preventInputFocus: false,
} };
}, },
methods: { methods: {
setFocusEvent() { setFocusEvent() {
document.querySelectorAll('.v-autocomplete input').forEach(input => { document.querySelectorAll('.v-autocomplete input').forEach((input) => {
input.addEventListener('focus', this.onInputFocus) input.addEventListener('focus', this.onInputFocus);
}) });
}, },
onDateFocus($event) { onDateFocus($event) {
if ($event == undefined) { if ($event == undefined) {
this.preventInputFocus = true this.preventInputFocus = true;
}
},
onDateOpen($event) {
if ($event == undefined) {
this.preventInputFocus = true;
} }
}, },
onInputFocus($event) { onInputFocus($event) {
setTimeout(() => {
if (this.preventInputFocus) { if (this.preventInputFocus) {
$event.target.blur() $event.target.blur();
this.preventInputFocus = false this.preventInputFocus = false;
} }
} }, 100);
} },
} },
};
@@ -3,91 +3,129 @@
<div v-if="deletable && editable" class="x-button"> <div v-if="deletable && editable" class="x-button">
<button @click="$emit('removeTimeblock')" class="x-button">x</button> <button @click="$emit('removeTimeblock')" class="x-button">x</button>
</div> </div>
<div @click="openDatepicker('datepicker')" class="datepicker-wrapper" ref="datepicker-wrapper"> <div
<Datepicker :model-value="timeblock.date" ref="datepicker" @focus="onDateFocus" @update:model-value="updateDate" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" :auto-apply="true" :enable-time-picker="false" class="mb-5 modal-input datepicker-input" /> @click="openDatepicker('datepicker')"
class="datepicker-wrapper"
ref="datepicker-wrapper"
>
<Datepicker
:model-value="timeblock.date"
ref="datepicker"
@open="onDateOpen"
@update:model-value="updateDate"
format="dd.MM.yyyy"
locale="sk"
select-text="Vybrať"
cancel-text="Zrušiť"
placeholder="Dátum"
:auto-apply="true"
:enable-time-picker="false"
class="mb-5 modal-input datepicker-input"
/>
</div> </div>
<div class="splitted-time-inputs"> <div class="splitted-time-inputs">
<v-text-field :value="timeblock.starts_at_time" @input="updateStartTime" @focus="onInputFocus" :class="{ error: v$?.timeblock.starts_at_time.$errors.length }" type="time" variant="solo" bg-color="white" label="Začiatok" /> <v-text-field
<v-text-field :value="timeblock.ends_at_time" @input="updateEndTime" @focus="onInputFocus" :class="{ error: v$?.timeblock.ends_at_time.$errors.length }" type="time" variant="solo" bg-color="white" label="Koniec" /> :value="timeblock.starts_at_time"
@input="updateStartTime"
@focus="onInputFocus"
:class="{ error: v$?.timeblock.starts_at_time.$errors.length }"
type="time"
variant="solo"
bg-color="white"
label="Začiatok"
/>
<v-text-field
:value="timeblock.ends_at_time"
@input="updateEndTime"
@focus="onInputFocus"
:class="{ error: v$?.timeblock.ends_at_time.$errors.length }"
type="time"
variant="solo"
bg-color="white"
label="Koniec"
/>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import useVuelidate from '@vuelidate/core' import useVuelidate from '@vuelidate/core';
import { requiredIf } from '@vuelidate/validators' import { requiredIf } from '@vuelidate/validators';
import Datepicker from '@vuepic/vue-datepicker' import Datepicker from '@vuepic/vue-datepicker';
import VuetifyFixFocusMixin from '@/plugins/tm@modal/_mixins/vuetify-fix-focus'
export default { export default {
mixins: [VuetifyFixFocusMixin],
components: { components: {
Datepicker Datepicker,
}, },
props: { props: {
timeblock: { timeblock: {
type: Object, type: Object,
required: true required: true,
}, },
deletable: { deletable: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
editable: { editable: {
type: Boolean, type: Boolean,
default: false default: false,
} },
preventInputFocus: {
type: Boolean,
default: false,
},
onInputFocus: {
type: Function,
default: () => ({}),
},
onDateOpen: {
type: Function,
default: () => ({}),
},
}, },
data() { data() {
return { return {
v$: useVuelidate(), v$: useVuelidate(),
} };
}, },
validations() { validations() {
return { return {
timeblock: { timeblock: {
starts_at_time: { required: requiredIf(this.timeblock.date) }, starts_at_time: { required: requiredIf(this.timeblock.date) },
ends_at_time: { required: requiredIf(this.timeblock.date) } ends_at_time: { required: requiredIf(this.timeblock.date) },
} },
} };
}, },
methods: { methods: {
async openDatepicker(ref) { async openDatepicker(ref) {
this.$refs[ref].openMenu() this.$refs[ref].openMenu();
this.$nextTick(() => {
this.$refs['datepicker-wrapper'].scrollIntoView({ behavior: 'instant', block: 'center', inline: 'center' })
this.$nextTick(() => {
const popup = document.querySelector('.dp__menu.dp__menu_index')
const isBottom = popup.querySelector('.dp__arrow_bottom')
const yDifference = isBottom ? 0 - popup.clientHeight - 42 : 35
popup.style.top = window.innerHeight / 2 + yDifference + 'px'
})
})
}, },
updateDate(date) { updateDate(date) {
const timeblock = { ...this.timeblock } const timeblock = { ...this.timeblock };
if (date) timeblock.date = date if (date) timeblock.date = date;
this.$emit('updateTimeblock', timeblock) this.$emit('updateTimeblock', timeblock);
}, },
updateStartTime(event) { updateStartTime(event) {
const timeblock = { ...this.timeblock } const timeblock = { ...this.timeblock };
timeblock.starts_at_time = event.target.value timeblock.starts_at_time = event.target.value;
this.$emit('updateTimeblock', timeblock) this.$emit('updateTimeblock', timeblock);
}, },
updateEndTime(event) { updateEndTime(event) {
const timeblock = { ...this.timeblock } const timeblock = { ...this.timeblock };
timeblock.ends_at_time = event.target.value timeblock.ends_at_time = event.target.value;
this.$emit('updateTimeblock', timeblock) this.$emit('updateTimeblock', timeblock);
}, },
} },
} };
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
@@ -119,4 +157,5 @@ export default {
.datepicker-input .datepicker-input
width: 100% !important width: 100% !important
pointer-events: none pointer-events: none
</style>e </style>
e
+5 -16
View File
@@ -44,6 +44,7 @@
variant="solo" variant="solo"
class="modal-input" class="modal-input"
clearable clearable
@focus="onInputFocus"
/> />
<v-text-field <v-text-field
@@ -62,7 +63,7 @@
> >
<Datepicker <Datepicker
v-model="subtask.deadline" v-model="subtask.deadline"
@focus="onDateFocus" @open="onDateOpen"
ref="datepicker-01" ref="datepicker-01"
:auto-apply="true" :auto-apply="true"
:min-date="new Date()" :min-date="new Date()"
@@ -233,14 +234,6 @@
</div> </div>
</template> </template>
<!-- <div class="w-100">
<Datepicker v-model="subtask.date" :class="{ error: v$.subtask.date.$errors.length }" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" :auto-apply="true" :enable-time-picker="false" @focus="onDateFocus" class="mb-5 modal-input" />
<div class="splitted-time-inputs">
<v-text-field :class="{ error: v$.subtask.starts_at_time.$errors.length }" type="time" variant="solo" bg-color="white" label="Začiatok" />
<v-text-field :class="{ error: v$.subtask.ends_at_time.$errors.length }" type="time" variant="solo" bg-color="white" label="Koniec" />
</div>
</div> -->
<template v-if="!subtask.id"> <template v-if="!subtask.id">
<div class="timeblocks w-100"> <div class="timeblocks w-100">
<A-timeblock <A-timeblock
@@ -252,6 +245,9 @@
:deletable="index > 0" :deletable="index > 0"
editable editable
:ref="`timetable-${index}`" :ref="`timetable-${index}`"
:prevent-input-focus="preventInputFocus"
:on-input-focus="onInputFocus"
:on-date-open="onDateOpen"
/> />
<div class="end-button w-100"> <div class="end-button w-100">
<button <button
@@ -373,13 +369,6 @@
@close-modal="closeModal" @close-modal="closeModal"
@update-subtask="updateSubtask" @update-subtask="updateSubtask"
/> />
<!-- <div class="mt-10">
<p>Termín</p>
<div class="date-wrap">
<Datepicker @open="editDatepicker('date')" v-model="subtask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" />
<Datepicker @open="editDatepicker('time')" v-model="subtask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input" format="HH:mm" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Čas" />
</div>
</div> -->
<div class="d-flex justify-start align-center mt-8"> <div class="d-flex justify-start align-center mt-8">
<v-btn <v-btn