summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
blob: f266d978ffa979c0bf34675014ff694794501080 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<script>
import { uniqueId } from 'lodash';
import Api from '~/api';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import { GROUP_FILTERS, GROUP_MODAL_LABELS } from '../constants';
import eventHub from '../event_hub';
import { getInvalidFeedbackMessage } from '../utils/get_invalid_feedback_message';
import GroupSelect from './group_select.vue';
import InviteModalBase from './invite_modal_base.vue';

export default {
  name: 'InviteMembersModal',
  components: {
    GroupSelect,
    InviteModalBase,
  },
  props: {
    id: {
      type: String,
      required: true,
    },
    isProject: {
      type: Boolean,
      required: true,
    },
    name: {
      type: String,
      required: true,
    },
    accessLevels: {
      type: Object,
      required: true,
    },
    defaultAccessLevel: {
      type: Number,
      required: true,
    },
    helpLink: {
      type: String,
      required: true,
    },
    groupSelectFilter: {
      type: String,
      required: false,
      default: GROUP_FILTERS.ALL,
    },
    groupSelectParentId: {
      type: Number,
      required: false,
      default: null,
    },
    invalidGroups: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      invalidFeedbackMessage: '',
      isLoading: false,
      modalId: uniqueId('invite-groups-modal-'),
      groupToBeSharedWith: {},
    };
  },
  computed: {
    labelIntroText() {
      return this.$options.labels[this.inviteTo].introText;
    },
    inviteTo() {
      return this.isProject ? 'toProject' : 'toGroup';
    },
    toastOptions() {
      return {
        onComplete: () => {
          this.groupToBeSharedWith = {};
        },
      };
    },
    inviteDisabled() {
      return Object.keys(this.groupToBeSharedWith).length === 0;
    },
  },
  mounted() {
    eventHub.$on('openGroupModal', () => {
      this.openModal();
    });
  },
  methods: {
    showInvalidFeedbackMessage(response) {
      this.invalidFeedbackMessage = getInvalidFeedbackMessage(response);
    },
    openModal() {
      this.$root.$emit(BV_SHOW_MODAL, this.modalId);
    },
    closeModal() {
      this.$root.$emit(BV_HIDE_MODAL, this.modalId);
    },
    sendInvite({ accessLevel, expiresAt }) {
      this.invalidFeedbackMessage = '';
      this.isLoading = true;

      const apiShareWithGroup = this.isProject
        ? Api.projectShareWithGroup.bind(Api)
        : Api.groupShareWithGroup.bind(Api);

      apiShareWithGroup(this.id, {
        format: 'json',
        group_id: this.groupToBeSharedWith.id,
        group_access: accessLevel,
        expires_at: expiresAt,
      })
        .then(() => {
          this.showSuccessMessage();
        })
        .catch((e) => {
          this.showInvalidFeedbackMessage(e);
        })
        .finally(() => {
          this.isLoading = false;
        });
    },
    resetFields() {
      this.invalidFeedbackMessage = '';
      this.isLoading = false;
      this.groupToBeSharedWith = {};
    },
    showSuccessMessage() {
      this.$toast.show(this.$options.labels.toastMessageSuccessful, this.toastOptions);
      this.closeModal();
    },
    clearValidation() {
      this.invalidFeedbackMessage = '';
    },
  },
  labels: GROUP_MODAL_LABELS,
};
</script>
<template>
  <invite-modal-base
    :modal-id="modalId"
    :modal-title="$options.labels.title"
    :name="name"
    :access-levels="accessLevels"
    :default-access-level="defaultAccessLevel"
    :help-link="helpLink"
    v-bind="$attrs"
    :label-intro-text="labelIntroText"
    :label-search-field="$options.labels.searchField"
    :submit-disabled="inviteDisabled"
    :invalid-feedback-message="invalidFeedbackMessage"
    :is-loading="isLoading"
    @reset="resetFields"
    @submit="sendInvite"
  >
    <template #select>
      <group-select
        v-model="groupToBeSharedWith"
        :access-levels="accessLevels"
        :groups-filter="groupSelectFilter"
        :parent-group-id="groupSelectParentId"
        :invalid-groups="invalidGroups"
        @input="clearValidation"
      />
    </template>
  </invite-modal-base>
</template>