diff --git a/ui/src/components/view/DedicateModal.vue b/ui/src/components/view/DedicateModal.vue index caf564eefaf..1b9e9d5a4db 100644 --- a/ui/src/components/view/DedicateModal.vue +++ b/ui/src/components/view/DedicateModal.vue @@ -18,16 +18,20 @@ @@ -63,7 +67,8 @@ export default { dedicatedDomainModal: false, domainId: null, dedicatedAccount: null, - domainError: false + domainError: false, + isSubmitted: false } }, watch: { @@ -100,11 +105,13 @@ export default { this.fetchParentData() this.dedicatedDomainId = this.domainId this.dedicatedDomainModal = false + this.isSubmitted = false }, errorMessage: this.$t('error.dedicate.zone.failed'), errorMethod: () => { this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false }, loadingMessage: this.$t('message.dedicating.zone'), catchMessage: this.$t('error.fetching.async.job.result'), @@ -112,11 +119,13 @@ export default { this.parentFetchData() this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false } }) }).catch(error => { this.$notifyError(error) this.dedicatedDomainModal = false + this.isSubmitted = false }) }, dedicatePod () { @@ -138,11 +147,13 @@ export default { this.fetchParentData() this.dedicatedDomainId = this.domainId this.dedicatedDomainModal = false + this.isSubmitted = false }, errorMessage: this.$t('error.dedicate.pod.failed'), errorMethod: () => { this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false }, loadingMessage: this.$t('message.dedicating.pod'), catchMessage: this.$t('error.fetching.async.job.result'), @@ -150,11 +161,13 @@ export default { this.parentFetchData() this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false } }) }).catch(error => { this.$notifyError(error) this.dedicatedDomainModal = false + this.isSubmitted = false }) }, dedicateCluster () { @@ -176,11 +189,13 @@ export default { this.fetchParentData() this.dedicatedDomainId = this.domainId this.dedicatedDomainModal = false + this.isSubmitted = false }, errorMessage: this.$t('error.dedicate.cluster.failed'), errorMethod: () => { this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false }, loadingMessage: this.$t('message.dedicating.cluster'), catchMessage: this.$t('error.fetching.async.job.result'), @@ -188,11 +203,13 @@ export default { this.parentFetchData() this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false } }) }).catch(error => { this.$notifyError(error) this.dedicatedDomainModal = false + this.isSubmitted = false }) }, dedicateHost () { @@ -214,11 +231,13 @@ export default { this.fetchParentData() this.dedicatedDomainId = this.domainId this.dedicatedDomainModal = false + this.isSubmitted = false }, errorMessage: this.$t('error.dedicate.host.failed'), errorMethod: () => { this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false }, loadingMessage: this.$t('message.dedicating.host'), catchMessage: this.$t('error.fetching.async.job.result'), @@ -226,14 +245,20 @@ export default { this.parentFetchData() this.fetchParentData() this.dedicatedDomainModal = false + this.isSubmitted = false } }) }).catch(error => { this.$notifyError(error) this.dedicatedDomainModal = false + this.isSubmitted = false }) }, handleDedicateForm () { + if (this.isSubmitted) { + return + } + this.isSubmitted = true if (this.$route.meta.name === 'zone') { this.dedicateZone() } diff --git a/ui/src/components/view/FormView.vue b/ui/src/components/view/FormView.vue index 60566aaff78..020f280b540 100644 --- a/ui/src/components/view/FormView.vue +++ b/ui/src/components/view/FormView.vue @@ -21,10 +21,7 @@ :visible="showForm" :closable="true" :confirmLoading="currentAction.loading" - :okText="$t('label.ok')" - :cancelText="$t('label.cancel')" style="top: 20px;" - @ok="handleSubmit" @cancel="close" centered > diff --git a/ui/src/components/view/ResourceLimitTab.vue b/ui/src/components/view/ResourceLimitTab.vue index e12eb214b5c..f8839e61ca6 100644 --- a/ui/src/components/view/ResourceLimitTab.vue +++ b/ui/src/components/view/ResourceLimitTab.vue @@ -21,6 +21,7 @@ :form="form" @submit="handleSubmit" layout="vertical" + v-ctrl-enter="handleSubmit" > { if (err) { return diff --git a/ui/src/main.js b/ui/src/main.js index 9fbae3e0acd..8eda9180411 100644 --- a/ui/src/main.js +++ b/ui/src/main.js @@ -28,6 +28,7 @@ import './permission' // permission control import './utils/filter' // global filter import { pollJobPlugin, notifierPlugin, toLocaleDatePlugin, configUtilPlugin, apiMetaUtilPlugin } from './utils/plugins' import { VueAxios } from './utils/request' +import './utils/directives' Vue.config.productionTip = false Vue.use(VueAxios, router) diff --git a/ui/src/style/vars.less b/ui/src/style/vars.less index 7ee21618a5c..2bd87d6561e 100644 --- a/ui/src/style/vars.less +++ b/ui/src/style/vars.less @@ -241,8 +241,17 @@ a { } } +.action-button { + text-align: right; + padding-top: 15px; + + button { + margin-right: 5px; + } +} + @media only screen and (max-width: 576px) { .ant-pagination-options { display: inline-block; } -} \ No newline at end of file +} diff --git a/ui/src/utils/directives.js b/ui/src/utils/directives.js new file mode 100644 index 00000000000..b039e06e769 --- /dev/null +++ b/ui/src/utils/directives.js @@ -0,0 +1,47 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import Vue from 'vue' + +const ENTER_KEY_CODE = 13 +let lastFocusElm = null + +Vue.directive('ctrlEnter', { + bind: (el, binding, vnode) => { + el.addEventListener('keydown', (e) => { + if (e.ctrlKey && e.keyCode === ENTER_KEY_CODE) { + e.preventDefault() + lastFocusElm = e.target + vnode.context.$refs.submit.$el.focus() + } + }) + + el.addEventListener('keyup', (e) => { + if (!e.ctrlKey || e.keyCode !== ENTER_KEY_CODE) { + e.preventDefault() + return + } + + e.preventDefault() + if (typeof binding.value === 'function') { + if (lastFocusElm) lastFocusElm.focus() + const argument = binding.arg || e + binding.value(argument) + } + }) + } +}) diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 6b6bab4c3cd..427160f776d 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -124,15 +124,14 @@ :visible="showAction" :closable="true" :maskClosable="false" - :okText="$t('label.ok')" - :cancelText="$t('label.cancel')" + :footer="null" style="top: 20px;" :width="modalWidth" - @ok="handleSubmit" - @cancel="closeAction" :ok-button-props="getOkProps()" :cancel-button-props="getCancelProps()" :confirmLoading="actionLoading" + @cancel="closeAction" + v-ctrl-enter="handleSubmit" centered > @@ -322,6 +321,11 @@ :placeholder="field.description" /> + +
+ {{ $t('label.cancel') }} + {{ $t('label.ok') }} +

@@ -764,7 +768,7 @@ export default { params.page = this.page params.pagesize = this.pageSize - this.searchParams = params + api(this.apiName, params).then(json => { var responseName var objectName @@ -852,6 +856,7 @@ export default { } }).finally(f => { this.loading = false + this.searchParams = params }) }, closeAction () { @@ -1077,6 +1082,7 @@ export default { this.message = {} }, handleSubmit (e) { + if (this.actionLoading) return this.promises = [] if (!this.dataView && this.currentAction.groupAction && this.selectedRowKeys.length > 0) { if (this.selectedRowKeys.length > 0) { diff --git a/ui/src/views/auth/Login.vue b/ui/src/views/auth/Login.vue index 42c713721c7..6966d5a5b22 100644 --- a/ui/src/views/auth/Login.vue +++ b/ui/src/views/auth/Login.vue @@ -22,6 +22,7 @@ ref="formLogin" :form="form" @submit="handleSubmit" + v-ctrl-enter="handleSubmit" > {{ $t('label.login') }} @@ -169,6 +171,7 @@ export default { customActiveKey, Login } = this + if (state.loginBtn) return state.loginBtn = true diff --git a/ui/src/views/compute/AssignInstance.vue b/ui/src/views/compute/AssignInstance.vue index 883e4b3e76f..23da3e2e85d 100644 --- a/ui/src/views/compute/AssignInstance.vue +++ b/ui/src/views/compute/AssignInstance.vue @@ -17,7 +17,7 @@