diff --git a/src/boot/mainShortcutMixin.js b/src/boot/mainShortcutMixin.js new file mode 100644 index 000000000..481077e37 --- /dev/null +++ b/src/boot/mainShortcutMixin.js @@ -0,0 +1,36 @@ +import routes from 'src/router/modules'; +import { useRouter } from 'vue-router'; + +let isNotified = false; + +export default { + created: function () { + const router = useRouter(); + const keyBindingMap = routes + .filter((route) => route.meta.keyBinding) + .reduce((map, route) => { + map['Key' + route.meta.keyBinding.toUpperCase()] = route.path; + return map; + }, {}); + + const handleKeyDown = (event) => { + const { ctrlKey, altKey, code } = event; + + if (ctrlKey && altKey && keyBindingMap[code] && !isNotified) { + event.preventDefault(); + router.push(keyBindingMap[code]); + isNotified = true; + } + }; + + const handleKeyUp = (event) => { + const { ctrlKey, altKey } = event; + if (!ctrlKey || !altKey) { + isNotified = false; + } + }; + + window.addEventListener('keydown', handleKeyDown); + window.addEventListener('keyup', handleKeyUp); + }, +}; diff --git a/src/boot/qformMixin.js b/src/boot/qformMixin.js index fc7852369..8a75e1af7 100644 --- a/src/boot/qformMixin.js +++ b/src/boot/qformMixin.js @@ -1,30 +1,52 @@ -import { getCurrentInstance } from 'vue'; - +function focusFirstInput(input) { + input.focus(); + return; +} export default { mounted: function () { - const vm = getCurrentInstance(); - if (vm.type.name === 'QForm') { - if (!['searchbarForm', 'filterPanelForm'].includes(this.$el?.id)) { - // TODO: AUTOFOCUS IS NOT FOCUSING - const that = this; - this.$el.addEventListener('keyup', function (evt) { - if (evt.key === 'Enter') { - const input = evt.target; - if (input.type == 'textarea' && evt.shiftKey) { - evt.preventDefault(); - let { selectionStart, selectionEnd } = input; - input.value = - input.value.substring(0, selectionStart) + - '\n' + - input.value.substring(selectionEnd); - selectionStart = selectionEnd = selectionStart + 1; - return; - } - evt.preventDefault(); - that.onSubmit(); - } - }); + const that = this; + + const form = document.querySelector('.q-form#formModel'); + if (!form) return; + try { + const inputsFormCard = form.querySelectorAll( + `input:not([disabled]):not([type="checkbox"])` + ); + if (inputsFormCard.length) { + focusFirstInput(inputsFormCard[0]); } + const textareas = document.querySelectorAll( + 'textarea:not([disabled]), [contenteditable]:not([disabled])' + ); + if (textareas.length) { + focusFirstInput(textareas[textareas.length - 1]); + } + const inputs = document.querySelectorAll( + 'form#formModel input:not([disabled]):not([type="checkbox"])' + ); + const input = inputs[0]; + if (!input) return; + + focusFirstInput(input); + } catch (error) { + console.error(error); } + form.addEventListener('keyup', function (evt) { + if (evt.key === 'Enter') { + const input = evt.target; + if (input.type == 'textarea' && evt.shiftKey) { + evt.preventDefault(); + let { selectionStart, selectionEnd } = input; + input.value = + input.value.substring(0, selectionStart) + + '\n' + + input.value.substring(selectionEnd); + selectionStart = selectionEnd = selectionStart + 1; + return; + } + evt.preventDefault(); + that.onSubmit(); + } + }); }, }; diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 01fe68d8b..d375c2f69 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -3,11 +3,16 @@ import qFormMixin from './qformMixin'; import keyShortcut from './keyShortcut'; import useNotify from 'src/composables/useNotify.js'; import { CanceledError } from 'axios'; +import { QForm } from 'quasar'; +import { QLayout } from 'quasar'; +import mainShortcutMixin from './mainShortcutMixin'; const { notify } = useNotify(); export default boot(({ app }) => { - app.mixin(qFormMixin); + QForm.mixins = [qFormMixin]; + QLayout.mixins = [mainShortcutMixin]; + app.directive('shortcut', keyShortcut); app.config.errorHandler = (error) => { let message; diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue index ab2931dfd..31ad9ebed 100644 --- a/src/components/LeftMenu.vue +++ b/src/components/LeftMenu.vue @@ -177,6 +177,7 @@ function normalize(text) { class="full-width" filled dense + autofocus /> diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 754b084fc..2a84e5aa1 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -1,50 +1,10 @@ - diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue index 94f4e0d95..3ceee2493 100644 --- a/src/pages/Worker/Card/WorkerPda.vue +++ b/src/pages/Worker/Card/WorkerPda.vue @@ -133,6 +133,7 @@ function reloadData() { option-value="id" id="deviceProductionFk" hide-selected + data-cy="pda-dialog-select" >