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
|
import { uniqueId } from 'lodash';
import { __, n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { EXTENSION_ICONS } from '../../constants';
export default {
name: 'WidgetAccessibility',
enablePolling: true,
telemetry: false,
i18n: {
loading: s__('Reports|Accessibility scanning results are being parsed'),
error: s__('Reports|Accessibility scanning failed loading results'),
},
props: ['accessibilityReportPath'],
computed: {
statusIcon() {
return this.collapsedData.status === 'failed'
? EXTENSION_ICONS.warning
: EXTENSION_ICONS.success;
},
},
methods: {
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 ? successText : warningText;
},
fetchCollapsedData() {
return axios.get(this.accessibilityReportPath);
},
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 });
},
prepareReports() {
const { new_errors, existing_errors, resolved_errors } = this.collapsedData;
const newErrors = 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 = 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 = 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];
},
},
};
|