use an 'AsyncButton' that waits for completion of an async onClick handler for mail replies and comments in tickets
This commit is contained in:
parent
3a8fa8cdcf
commit
6e38ff7ac7
2 changed files with 58 additions and 13 deletions
|
@ -40,10 +40,10 @@
|
||||||
<div class="">
|
<div class="">
|
||||||
<textarea placeholder="add comment..." v-model="newComment" class="form-control">
|
<textarea placeholder="add comment..." v-model="newComment" class="form-control">
|
||||||
</textarea>
|
</textarea>
|
||||||
<button class="btn btn-primary float-right" @click="addCommentAndClear">
|
<AsyncButton class="btn btn-primary float-right" :task="addCommentAndClear">
|
||||||
<font-awesome-icon icon="comment"/>
|
<font-awesome-icon icon="comment"/>
|
||||||
Save Comment
|
Save Comment
|
||||||
</button>
|
</AsyncButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -58,10 +58,10 @@
|
||||||
<div>
|
<div>
|
||||||
<textarea placeholder="reply mail..." v-model="newMail" class="form-control">
|
<textarea placeholder="reply mail..." v-model="newMail" class="form-control">
|
||||||
</textarea>
|
</textarea>
|
||||||
<button class="btn btn-primary float-right" @click="sendMailAndClear">
|
<AsyncButton class="btn btn-primary float-right" :task="sendMailAndClear">
|
||||||
<font-awesome-icon icon="envelope"/>
|
<font-awesome-icon icon="envelope"/>
|
||||||
Send Mail
|
Send Mail
|
||||||
</button>
|
</AsyncButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -77,11 +77,12 @@ import {mapActions, mapGetters} from "vuex";
|
||||||
import TimelineAssignment from "@/components/TimelineAssignment.vue";
|
import TimelineAssignment from "@/components/TimelineAssignment.vue";
|
||||||
import TimelineRelatedItem from "@/components/TimelineRelatedItem.vue";
|
import TimelineRelatedItem from "@/components/TimelineRelatedItem.vue";
|
||||||
import TimelineShippingVoucher from "@/components/TimelineShippingVoucher.vue";
|
import TimelineShippingVoucher from "@/components/TimelineShippingVoucher.vue";
|
||||||
|
import AsyncButton from "@/components/inputs/AsyncButton.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Timeline',
|
name: 'Timeline',
|
||||||
components: {
|
components: {
|
||||||
TimelineShippingVoucher,
|
TimelineShippingVoucher, AsyncButton,
|
||||||
TimelineRelatedItem, TimelineAssignment, TimelineStateChange, TimelineComment, TimelineMail
|
TimelineRelatedItem, TimelineAssignment, TimelineStateChange, TimelineComment, TimelineMail
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -103,18 +104,15 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['fetchShippingVouchers']),
|
...mapActions(['sendMail', 'postComment']),
|
||||||
sendMailAndClear: function () {
|
sendMailAndClear: async function () {
|
||||||
this.$emit('sendMail', this.newMail);
|
await this.sendMail(this.newMail);
|
||||||
this.newMail = "";
|
this.newMail = "";
|
||||||
},
|
},
|
||||||
addCommentAndClear: function () {
|
addCommentAndClear: async function () {
|
||||||
this.$emit('addComment', this.newComment);
|
await this.postComment(this.newComment);
|
||||||
this.newComment = "";
|
this.newComment = "";
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.fetchShippingVouchers();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
47
web/src/components/inputs/AsyncButton.vue
Normal file
47
web/src/components/inputs/AsyncButton.vue
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<button @click.stop="handleClick" :disabled="disabled">
|
||||||
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"
|
||||||
|
:class="{'d-none': !disabled}"></span>
|
||||||
|
<span class="ml-2" :class="{'d-none': !disabled}">In Progress...</span>
|
||||||
|
<span :class="{'d-none': disabled}"><slot></slot></span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AsyncButton',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
task: {
|
||||||
|
type: Function,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async handleClick() {
|
||||||
|
console.log("AsyncButton.handleClick() called");
|
||||||
|
if (this.task && typeof this.task === 'function') {
|
||||||
|
this.disabled = true;
|
||||||
|
try {
|
||||||
|
await this.task();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
this.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.spinner-border {
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in a new issue