async_button.vue 1.63 KB
Newer Older
1
<script>
2
  /* eslint-disable no-alert, vue/require-default-prop */
3

4 5
  import eventHub from '../event_hub';
  import loadingIcon from '../../vue_shared/components/loading_icon.vue';
6
  import icon from '../../vue_shared/components/icon.vue';
7
  import tooltip from '../../vue_shared/directives/tooltip';
8

9 10 11
  export default {
    directives: {
      tooltip,
12
    },
13 14 15

    components: {
      loadingIcon,
16
      icon,
17
    },
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
    props: {
      endpoint: {
        type: String,
        required: true,
      },
      title: {
        type: String,
        required: true,
      },
      icon: {
        type: String,
        required: true,
      },
      cssClass: {
        type: String,
        required: true,
      },
      confirmActionMessage: {
        type: String,
        required: false,
      },
39
    },
40

41 42 43 44
    data() {
      return {
        isLoading: false,
      };
45
    },
46 47 48 49
    computed: {
      buttonClass() {
        return `btn ${this.cssClass}`;
      },
50
    },
51 52 53 54 55 56 57 58 59 60
    methods: {
      onClick() {
        if (this.confirmActionMessage && confirm(this.confirmActionMessage)) {
          this.makeRequest();
        } else if (!this.confirmActionMessage) {
          this.makeRequest();
        }
      },
      makeRequest() {
        this.isLoading = true;
61

62 63
        eventHub.$emit('postAction', this.endpoint);
      },
64
    },
65
  };
66 67 68 69
</script>

<template>
  <button
70
    v-tooltip
71 72 73 74 75 76 77
    type="button"
    @click="onClick"
    :class="buttonClass"
    :title="title"
    :aria-label="title"
    data-container="body"
    data-placement="top"
78
    :disabled="isLoading">
79 80 81
    <icon
      :name="icon"
    />
82
    <loading-icon v-if="isLoading" />
83
  </button>
84
</template>