diff options
Diffstat (limited to 'app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue')
-rw-r--r-- | app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue b/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue new file mode 100644 index 00000000000..8f3610b912a --- /dev/null +++ b/app/assets/javascripts/sidebar/components/severity/sidebar_severity.vue @@ -0,0 +1,187 @@ +<script> +import { + GlDropdown, + GlDropdownItem, + GlLoadingIcon, + GlTooltip, + GlSprintf, + GlLink, +} from '@gitlab/ui'; +import { INCIDENT_SEVERITY, ISSUABLE_TYPES, I18N } from './constants'; +import updateIssuableSeverity from './graphql/mutations/update_issuable_severity.mutation.graphql'; +import SeverityToken from './severity.vue'; +import createFlash from '~/flash'; + +export default { + i18n: I18N, + components: { + GlLoadingIcon, + GlTooltip, + GlSprintf, + GlDropdown, + GlDropdownItem, + GlLink, + SeverityToken, + }, + props: { + projectPath: { + type: String, + required: true, + }, + iid: { + type: String, + required: true, + }, + initialSeverity: { + type: String, + required: false, + default: INCIDENT_SEVERITY.UNKNOWN.value, + }, + issuableType: { + type: String, + required: false, + default: ISSUABLE_TYPES.INCIDENT, + validator: value => { + // currently severity is supported only for incidents, but this list might be extended + return [ISSUABLE_TYPES.INCIDENT].includes(value); + }, + }, + }, + data() { + return { + isDropdownShowing: false, + isUpdating: false, + severity: this.initialSeverity, + }; + }, + computed: { + severitiesList() { + switch (this.issuableType) { + case ISSUABLE_TYPES.INCIDENT: + return Object.values(INCIDENT_SEVERITY); + default: + return []; + } + }, + dropdownClass() { + return this.isDropdownShowing ? 'show' : 'gl-display-none'; + }, + selectedItem() { + return this.severitiesList.find(severity => severity.value === this.severity); + }, + }, + mounted() { + document.addEventListener('click', this.handleOffClick); + }, + beforeDestroy() { + document.removeEventListener('click', this.handleOffClick); + }, + methods: { + handleOffClick(event) { + if (!this.isDropdownShowing) { + return; + } + + if (!this.$refs.sidebarSeverity.contains(event.target)) { + this.hideDropdown(); + } + }, + hideDropdown() { + this.isDropdownShowing = false; + const event = new Event('hidden.gl.dropdown'); + this.$el.dispatchEvent(event); + }, + toggleFormDropdown() { + this.isDropdownShowing = !this.isDropdownShowing; + }, + updateSeverity(value) { + this.hideDropdown(); + this.isUpdating = true; + this.$apollo + .mutate({ + mutation: updateIssuableSeverity, + variables: { + iid: this.iid, + severity: value, + projectPath: this.projectPath, + }, + }) + .then(resp => { + const { + data: { + issueSetSeverity: { + errors = [], + issue: { severity }, + }, + }, + } = resp; + + if (errors[0]) { + throw errors[0]; + } + this.severity = severity; + }) + .catch(() => + createFlash({ + message: `${this.$options.i18n.UPDATE_SEVERITY_ERROR} ${this.$options.i18n.TRY_AGAIN}`, + }), + ) + .finally(() => { + this.isUpdating = false; + }); + }, + }, +}; +</script> + +<template> + <div ref="sidebarSeverity" class="block"> + <div ref="severity" class="sidebar-collapsed-icon" @click="toggleFormDropdown"> + <severity-token :severity="selectedItem" :icon-size="14" :icon-only="true" /> + <gl-tooltip :target="() => $refs.severity" boundary="viewport" placement="left"> + <gl-sprintf :message="$options.i18n.SEVERITY_VALUE"> + <template #severity> + {{ selectedItem.label }} + </template> + </gl-sprintf> + </gl-tooltip> + </div> + + <div class="hide-collapsed"> + <p class="title gl-display-flex gl-justify-content-space-between"> + {{ $options.i18n.SEVERITY }} + <gl-link + data-testid="editButton" + href="#" + @click="toggleFormDropdown" + @keydown.esc="hideDropdown" + > + {{ $options.i18n.EDIT }} + </gl-link> + </p> + + <gl-dropdown + :class="dropdownClass" + block + :text="selectedItem.label" + toggle-class="dropdown-menu-toggle gl-mb-2" + @keydown.esc.native="hideDropdown" + > + <gl-dropdown-item + v-for="option in severitiesList" + :key="option.value" + data-testid="severityDropdownItem" + :is-check-item="true" + :is-checked="option.value === severity" + @click="updateSeverity(option.value)" + > + <severity-token :severity="option" /> + </gl-dropdown-item> + </gl-dropdown> + + <gl-loading-icon v-if="isUpdating" :inline="true" /> + + <severity-token v-else-if="!isDropdownShowing" :severity="selectedItem" /> + </div> + </div> +</template> |