Commit 65b60516 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'pb-add-stuck-icon-for-job' into 'master'

Adds stuck icon to job

See merge request gitlab-org/gitlab!61271
parents 89c73227 60b2df5f
<script>
import { GlBadge, GlIcon, GlLink } from '@gitlab/ui';
import { GlBadge, GlIcon, GlLink, GlTooltipDirective } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { s__ } from '~/locale';
import { SUCCESS_STATUS } from '../../../constants';
export default {
iconSize: 12,
badgeSize: 'sm',
i18n: {
stuckText: s__('Jobs|Job is stuck. Check runners.'),
},
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
GlBadge,
GlIcon,
......@@ -55,6 +62,9 @@ export default {
canReadJob() {
return this.job?.userPermissions?.readBuild;
},
jobStuck() {
return this.job?.stuck;
},
},
};
</script>
......@@ -73,6 +83,14 @@ export default {
<span v-else data-testid="job-id-limited-access">{{ jobId }}</span>
<gl-icon
v-if="jobStuck"
v-gl-tooltip="$options.i18n.stuckText"
name="warning"
:size="$options.iconSize"
data-testid="stuck-icon"
/>
<div class="gl-display-flex gl-align-items-center">
<div v-if="jobRef" class="gl-max-w-15 gl-text-truncate">
<gl-icon
......
......@@ -59,6 +59,7 @@ query getJobs($fullPath: ID!, $statuses: [CiJobStatus!]) {
playable
cancelable
active
stuck
userPermissions {
readBuild
}
......
......@@ -18761,6 +18761,9 @@ msgstr ""
msgid "Jobs|Create CI/CD configuration file"
msgstr ""
msgid "Jobs|Job is stuck. Check runners."
msgstr ""
msgid "Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project."
msgstr ""
......
......@@ -7,6 +7,7 @@ import { mockJobsInTable } from '../../../mock_data';
const mockJob = mockJobsInTable[0];
const mockJobCreatedByTag = mockJobsInTable[1];
const mockJobLimitedAccess = mockJobsInTable[2];
const mockStuckJob = mockJobsInTable[3];
describe('Job Cell', () => {
let wrapper;
......@@ -17,6 +18,7 @@ describe('Job Cell', () => {
const findJobSha = () => wrapper.findByTestId('job-sha');
const findLabelIcon = () => wrapper.findByTestId('label-icon');
const findForkIcon = () => wrapper.findByTestId('fork-icon');
const findStuckIcon = () => wrapper.findByTestId('stuck-icon');
const findAllTagBadges = () => wrapper.findAllByTestId('job-tag-badge');
const findBadgeById = (id) => wrapper.findByTestId(id);
......@@ -120,4 +122,19 @@ describe('Job Cell', () => {
expect(findBadgeById(testId).text()).toBe(text);
});
});
describe('Job icons', () => {
it('stuck icon is not shown if job is not stuck', () => {
createComponent();
expect(findStuckIcon().exists()).toBe(false);
});
it('stuck icon is shown if job is stuck', () => {
createComponent(mockStuckJob);
expect(findStuckIcon().exists()).toBe(true);
expect(findStuckIcon().attributes('name')).toBe('warning');
});
});
});
......@@ -1322,6 +1322,7 @@ export const mockJobsInTable = [
playable: true,
cancelable: false,
active: false,
stuck: false,
userPermissions: { readBuild: true, __typename: 'JobPermissions' },
__typename: 'CiJob',
},
......@@ -1361,6 +1362,7 @@ export const mockJobsInTable = [
playable: false,
cancelable: false,
active: false,
stuck: false,
userPermissions: { readBuild: true, __typename: 'JobPermissions' },
__typename: 'CiJob',
},
......@@ -1407,9 +1409,65 @@ export const mockJobsInTable = [
playable: false,
cancelable: false,
active: false,
stuck: false,
userPermissions: { readBuild: false, __typename: 'JobPermissions' },
__typename: 'CiJob',
},
{
artifacts: { nodes: [], __typename: 'CiJobArtifactConnection' },
allowFailure: false,
status: 'PENDING',
scheduledAt: null,
manualJob: false,
triggered: null,
createdByTag: false,
detailedStatus: {
detailsPath: '/root/ci-project/-/jobs/2391',
group: 'pending',
icon: 'status_pending',
label: 'pending',
text: 'pending',
tooltip: 'pending',
action: {
buttonTitle: 'Cancel this job',
icon: 'cancel',
method: 'post',
path: '/root/ci-project/-/jobs/2391/cancel',
title: 'Cancel',
__typename: 'StatusAction',
},
__typename: 'DetailedStatus',
},
id: 'gid://gitlab/Ci::Build/2391',
refName: 'master',
refPath: '/root/ci-project/-/commits/master',
tags: [],
shortSha: '916330b4',
commitPath: '/root/ci-project/-/commit/916330b4fda5dae226524ceb51c756c0ed26679d',
pipeline: {
id: 'gid://gitlab/Ci::Pipeline/482',
path: '/root/ci-project/-/pipelines/482',
user: {
webPath: '/root',
avatarUrl:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
__typename: 'UserCore',
},
__typename: 'Pipeline',
},
stage: { name: 'build', __typename: 'CiStage' },
name: 'build_job',
duration: null,
finishedAt: null,
coverage: null,
retryable: false,
playable: false,
cancelable: true,
active: true,
stuck: true,
userPermissions: { readBuild: true, __typename: 'JobPermissions' },
__typename: 'CiJob',
},
];
export const mockJobsQueryResponse = {
......@@ -1495,6 +1553,7 @@ export const mockJobsQueryResponse = {
playable: false,
cancelable: false,
active: false,
stuck: false,
userPermissions: { readBuild: true, __typename: 'JobPermissions' },
__typename: 'CiJob',
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment