release_2024-11-13 #88
2 changed files with 58 additions and 13 deletions
|
@ -40,10 +40,10 @@
|
|||
<div class="">
|
||||
<textarea placeholder="add comment..." v-model="newComment" class="form-control">
|
||||
</textarea>
|
||||
<button class="btn btn-primary float-right" @click="addCommentAndClear">
|
||||
<AsyncButton class="btn btn-primary float-right" :task="addCommentAndClear">
|
||||
<font-awesome-icon icon="comment"/>
|
||||
Save Comment
|
||||
</button>
|
||||
</AsyncButton>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -58,10 +58,10 @@
|
|||
<div>
|
||||
<textarea placeholder="reply mail..." v-model="newMail" class="form-control">
|
||||
</textarea>
|
||||
<button class="btn btn-primary float-right" @click="sendMailAndClear">
|
||||
<AsyncButton class="btn btn-primary float-right" :task="sendMailAndClear">
|
||||
<font-awesome-icon icon="envelope"/>
|
||||
Send Mail
|
||||
</button>
|
||||
</AsyncButton>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -77,11 +77,12 @@ import {mapActions, mapGetters} from "vuex";
|
|||
import TimelineAssignment from "@/components/TimelineAssignment.vue";
|
||||
import TimelineRelatedItem from "@/components/TimelineRelatedItem.vue";
|
||||
import TimelineShippingVoucher from "@/components/TimelineShippingVoucher.vue";
|
||||
import AsyncButton from "@/components/inputs/AsyncButton.vue";
|
||||
|
||||
export default {
|
||||
name: 'Timeline',
|
||||
components: {
|
||||
TimelineShippingVoucher,
|
||||
TimelineShippingVoucher, AsyncButton,
|
||||
TimelineRelatedItem, TimelineAssignment, TimelineStateChange, TimelineComment, TimelineMail
|
||||
},
|
||||
props: {
|
||||
|
@ -103,18 +104,15 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['fetchShippingVouchers']),
|
||||
sendMailAndClear: function () {
|
||||
this.$emit('sendMail', this.newMail);
|
||||
...mapActions(['sendMail', 'postComment']),
|
||||
sendMailAndClear: async function () {
|
||||
await this.sendMail(this.newMail);
|
||||
this.newMail = "";
|
||||
},
|
||||
addCommentAndClear: function () {
|
||||
this.$emit('addComment', this.newComment);
|
||||
addCommentAndClear: async function () {
|
||||
await this.postComment(this.newComment);
|
||||
this.newComment = "";
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fetchShippingVouchers();
|
||||
}
|
||||
};
|
||||
</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