Welcome to mirror list, hosted at ThFree Co, Russian Federation.

index.vue « accessibility « extensions « vue_merge_request_widget « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2ae16eef4101dc3adfe5125f46f7efefda209753 (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
<script>
import { uniqueId } from 'lodash';
import { __, n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue';
import { EXTENSION_ICONS } from '../../constants';

export default {
  name: 'WidgetAccessibility',
  i18n: {
    loading: s__('Reports|Accessibility scanning results are being parsed'),
    error: s__('Reports|Accessibility scanning failed loading results'),
  },
  components: {
    MrWidget,
  },
  props: {
    mr: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      collapsedData: {},
      content: [],
    };
  },
  computed: {
    statusIcon() {
      return this.collapsedData?.status === 'failed'
        ? EXTENSION_ICONS.warning
        : EXTENSION_ICONS.success;
    },
    summary() {
      const numOfResults = this.collapsedData?.summary?.errored || 0;

      const successText = s__(
        'Reports|Accessibility scanning detected no issues for the source branch only',
      );
      const warningText = sprintf(
        n__(
          'Reports|Accessibility scanning detected %{strong_start}%{number}%{strong_end} issue for the source branch only',
          'Reports|Accessibility scanning detected %{strong_start}%{number}%{strong_end} issues for the source branch only',
          numOfResults,
        ),
        {
          number: numOfResults,
        },
        false,
      );

      return numOfResults === 0 ? { title: successText } : { title: warningText };
    },
    shouldCollapse() {
      return this.collapsedData?.summary?.errored > 0;
    },
  },
  methods: {
    fetchCollapsedData() {
      return axios.get(this.mr.accessibilityReportPath).then((response) => {
        this.collapsedData = response.data;
        this.content = this.getContent(response.data);

        return response;
      });
    },
    fetchFullData() {
      return Promise.resolve(this.prepareReports());
    },
    parsedTECHSCode(code) {
      /*
       * In issue code looks like "WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail"
       * or "WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.NoContent"
       *
       * The TECHS code is the "G18", "G168", "H91", etc. from the code which is used for the documentation.
       * Here we simply split the string on `.` and get the code in the 5th position
       */
      return code?.split('.')[4];
    },
    formatLearnMoreUrl(code) {
      const parsed = this.parsedTECHSCode(code);
      // eslint-disable-next-line @gitlab/require-i18n-strings
      return `https://www.w3.org/TR/WCAG20-TECHS/${parsed || 'Overview'}.html`;
    },
    formatText(code) {
      return sprintf(
        s__(
          'AccessibilityReport|The accessibility scanning found an error of the following type: %{code}',
        ),
        { code },
      );
    },
    formatMessage(message) {
      return sprintf(s__('AccessibilityReport|Message: %{message}'), { message });
    },
    getContent(collapsedData) {
      const newErrors = collapsedData.new_errors.map((error) => {
        return {
          header: __('New'),
          id: uniqueId('new-error-'),
          text: this.formatText(error.code),
          icon: { name: EXTENSION_ICONS.failed },
          link: {
            href: this.formatLearnMoreUrl(error.code),
            text: __('Learn more'),
          },
          supportingText: this.formatMessage(error.message),
        };
      });

      const existingErrors = collapsedData.existing_errors.map((error) => {
        return {
          id: uniqueId('existing-error-'),
          text: this.formatText(error.code),
          icon: { name: EXTENSION_ICONS.failed },
          link: {
            href: this.formatLearnMoreUrl(error.code),
            text: __('Learn more'),
          },
          supportingText: this.formatMessage(error.message),
        };
      });

      const resolvedErrors = collapsedData.resolved_errors.map((error) => {
        return {
          id: uniqueId('resolved-error-'),
          text: this.formatText(error.code),
          icon: { name: EXTENSION_ICONS.success },
          link: {
            href: this.formatLearnMoreUrl(error.code),
            text: __('Learn more'),
          },
          supportingText: this.formatMessage(error.message),
        };
      });

      return [...newErrors, ...existingErrors, ...resolvedErrors];
    },
  },
};
</script>
<template>
  <mr-widget
    :error-text="$options.i18n.error"
    :status-icon-name="statusIcon"
    :loading-text="$options.i18n.loading"
    :widget-name="$options.name"
    :summary="summary"
    :content="content"
    :is-collapsible="shouldCollapse"
    :fetch-collapsed-data="fetchCollapsedData"
  />
</template>