All files / ee/app/assets/javascripts/incidents_settings/components service_level_agreement_form.vue

5.88% Statements 1/17
0% Branches 0/6
0% Functions 0/6
5.88% Lines 1/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                          2x                                                                                                                                                                                                                                                                                                
<script>
import {
  GlButton,
  GlForm,
  GlFormCheckbox,
  GlFormGroup,
  GlFormInput,
  GlFormSelect,
  GlFormText,
  GlTab,
} from '@gitlab/ui';
import { s__ } from '~/locale';
 
const units = {
  minutes: {
    value: 'minutes',
    text: s__('IncidentSettings|minutes'),
    multiplier: 1,
    step: 15,
  },
  hours: {
    value: 'hours',
    text: s__('IncidentSettings|hours'),
    multiplier: 60,
    step: 1,
  },
};
 
export default {
  i18n: {
    description: s__(
      'IncidentSettings|Introduce a countdown timer in incident issues to better track Service Level Agreements (SLAs). The timer starts automatically when the incident is created, and sets a time limit for resolving the incident. When activated, the time to SLA countdown appears on all new incidents.',
    ),
    checkboxDetail: s__(
      'IncidentSettings|When activated, this applies to all new incidents in the project.',
    ),
    validFeedback: s__('IncidentSettings|Time limit must be a multiple of 15 minutes.'),
  },
  selectOptions: Object.values(units),
  units,
  components: {
    GlButton,
    GlForm,
    GlFormCheckbox,
    GlFormGroup,
    GlFormInput,
    GlFormSelect,
    GlFormText,
    GlTab,
  },
  inject: ['service', 'serviceLevelAgreementSettings'],
  data() {
    return {
      available: this.serviceLevelAgreementSettings.available,
      duration: this.serviceLevelAgreementSettings.minutes ?? '',
      enabled: this.serviceLevelAgreementSettings.active,
      loading: false,
      unit: this.$options.units.minutes.value,
    };
  },
  computed: {
    disableSubmit() {
      return this.loading || !this.showValidFeedback;
    },
    invalidFeedback() {
      // Don't validate when checkbox is disabled
      Iif (!this.enabled) {
        return '';
      }
 
      // This checks for empty and non-number values, because input elements of
      // type 'number' automatically convert a non-number input to an empty string.
      Iif (this.duration === '') {
        return s__('IncidentSettings|Time limit must be a valid number.');
      }
 
      Iif (this.duration <= 0) {
        return s__('IncidentSettings|Time limit must be greater than 0.');
      }
 
      // We're looking for a minutes value provided in multiples of 15
      const minutes = this.duration * this.$options.units[this.unit].multiplier;
      Iif (minutes % 15 !== 0) {
        return s__('IncidentSettings|Time limit must be a multiple of 15 minutes.');
      }
 
      return '';
    },
    showValidFeedback() {
      return !this.invalidFeedback;
    },
  },
  methods: {
    updateServiceLevelAgreementSettings() {
      this.loading = true;
 
      return this.service
        .updateSettings({
          sla_timer: this.enabled,
          sla_timer_minutes: this.duration * this.$options.units[this.unit].multiplier,
        })
        .catch(() => {
          this.loading = false;
        });
    },
  },
};
</script>
 
<template>
  <gl-tab
    v-if="available"
    key="service-level-agreement"
    :title="s__('IncidentSettings|Incident settings')"
    active
  >
    <gl-form class="gl-pt-3" @submit.prevent="updateServiceLevelAgreementSettings">
      <p class="gl-line-height-20">
        {{ $options.i18n.description }}
      </p>
      <gl-form-checkbox v-model="enabled" class="gl-my-4">
        <span>{{ s__('IncidentSettings|Activate "time to SLA" countdown timer') }}</span>
        <gl-form-text class="gl-font-base gl-text-gray-400">
          {{ $options.i18n.checkboxDetail }}
        </gl-form-text>
      </gl-form-checkbox>
      <gl-form-group
        :invalid-feedback="invalidFeedback"
        :label="s__('IncidentSettings|Time limit')"
        label-for="sla-duration"
        :state="showValidFeedback"
      >
        <div class="gl-display-flex gl-flex-direction-row">
          <gl-form-input
            id="sla-duration"
            v-model="duration"
            number
            width="xs"
            :step="$options.units[unit].step"
            type="number"
          />
          <gl-form-select
            v-model="unit"
            class="gl-w-auto gl-ml-3 gl-line-height-normal gl-border-gray-400"
            :options="$options.selectOptions"
          />
        </div>
        <template v-if="showValidFeedback" #description>
          {{ $options.i18n.validFeedback }}
        </template>
      </gl-form-group>
      <gl-button variant="confirm" type="submit" :disabled="disableSubmit" :loading="loading">
        {{ __('Save changes') }}
      </gl-button>
    </gl-form>
  </gl-tab>
</template>