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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-15 21:14:39 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-15 21:14:39 +0300
commit0f50c47cd7f7b88cc61e954d601b90fe7d12aac3 (patch)
tree8f376caa478ba32e57b665307970769ad7eecc34 /app/assets/javascripts/runner
parent78cfc7cf4afe0c7ffb72b8a9522b07873cd36820 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/runner')
-rw-r--r--app/assets/javascripts/runner/components/cells/link_cell.vue27
-rw-r--r--app/assets/javascripts/runner/components/runner_details.vue21
-rw-r--r--app/assets/javascripts/runner/components/runner_jobs.vue82
-rw-r--r--app/assets/javascripts/runner/components/runner_jobs_table.vue95
-rw-r--r--app/assets/javascripts/runner/constants.js2
-rw-r--r--app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql36
-rw-r--r--app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql1
7 files changed, 262 insertions, 2 deletions
diff --git a/app/assets/javascripts/runner/components/cells/link_cell.vue b/app/assets/javascripts/runner/components/cells/link_cell.vue
new file mode 100644
index 00000000000..2843ddbacaf
--- /dev/null
+++ b/app/assets/javascripts/runner/components/cells/link_cell.vue
@@ -0,0 +1,27 @@
+<script>
+import { GlLink } from '@gitlab/ui';
+
+export default {
+ props: {
+ href: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ computed: {
+ component() {
+ if (this.href) {
+ return GlLink;
+ }
+ return 'span';
+ },
+ },
+};
+</script>
+
+<template>
+ <component :is="component" :href="href" v-bind="$attrs" v-on="$listeners">
+ <slot></slot>
+ </component>
+</template>
diff --git a/app/assets/javascripts/runner/components/runner_details.vue b/app/assets/javascripts/runner/components/runner_details.vue
index ab4b99d4186..b6a5ffc7a64 100644
--- a/app/assets/javascripts/runner/components/runner_details.vue
+++ b/app/assets/javascripts/runner/components/runner_details.vue
@@ -1,22 +1,26 @@
<script>
-import { GlTabs, GlTab, GlIntersperse } from '@gitlab/ui';
+import { GlBadge, GlTabs, GlTab, GlIntersperse } from '@gitlab/ui';
import { s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
import { ACCESS_LEVEL_REF_PROTECTED, GROUP_TYPE, PROJECT_TYPE } from '../constants';
+import { formatJobCount } from '../utils';
import RunnerDetail from './runner_detail.vue';
import RunnerGroups from './runner_groups.vue';
import RunnerProjects from './runner_projects.vue';
+import RunnerJobs from './runner_jobs.vue';
import RunnerTags from './runner_tags.vue';
export default {
components: {
+ GlBadge,
GlTabs,
GlTab,
GlIntersperse,
RunnerDetail,
RunnerGroups,
RunnerProjects,
+ RunnerJobs,
RunnerTags,
TimeAgo,
},
@@ -53,6 +57,9 @@ export default {
isProjectRunner() {
return this.runner?.runnerType === PROJECT_TYPE;
},
+ jobCount() {
+ return formatJobCount(this.runner?.jobCount);
+ },
},
ACCESS_LEVEL_REF_PROTECTED,
};
@@ -65,7 +72,7 @@ export default {
<template v-if="runner">
<div class="gl-pt-4">
- <dl class="gl-mb-0">
+ <dl class="gl-mb-0" data-testid="runner-details-list">
<runner-detail :label="s__('Runners|Description')" :value="runner.description" />
<runner-detail
:label="s__('Runners|Last contact')"
@@ -103,5 +110,15 @@ export default {
<runner-projects v-if="isProjectRunner" :runner="runner" />
</template>
</gl-tab>
+ <gl-tab>
+ <template #title>
+ {{ s__('Runners|Jobs') }}
+ <gl-badge v-if="jobCount" data-testid="job-count-badge" class="gl-ml-1" size="sm">
+ {{ jobCount }}
+ </gl-badge>
+ </template>
+
+ <runner-jobs v-if="runner" :runner="runner" />
+ </gl-tab>
</gl-tabs>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_jobs.vue b/app/assets/javascripts/runner/components/runner_jobs.vue
new file mode 100644
index 00000000000..c13e7e90168
--- /dev/null
+++ b/app/assets/javascripts/runner/components/runner_jobs.vue
@@ -0,0 +1,82 @@
+<script>
+import { GlSkeletonLoading } from '@gitlab/ui';
+import { createAlert } from '~/flash';
+import getRunnerJobsQuery from '../graphql/get_runner_jobs.query.graphql';
+import { I18N_FETCH_ERROR, I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '../constants';
+import { captureException } from '../sentry_utils';
+import { getPaginationVariables } from '../utils';
+import RunnerJobsTable from './runner_jobs_table.vue';
+import RunnerPagination from './runner_pagination.vue';
+
+export default {
+ name: 'RunnerJobs',
+ components: {
+ GlSkeletonLoading,
+ RunnerJobsTable,
+ RunnerPagination,
+ },
+ props: {
+ runner: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ jobs: {
+ items: [],
+ pageInfo: {},
+ },
+ pagination: {
+ page: 1,
+ },
+ };
+ },
+ apollo: {
+ jobs: {
+ query: getRunnerJobsQuery,
+ variables() {
+ return this.variables;
+ },
+ update({ runner }) {
+ return {
+ items: runner?.jobs?.nodes || [],
+ pageInfo: runner?.jobs?.pageInfo || {},
+ };
+ },
+ error(error) {
+ createAlert({ message: I18N_FETCH_ERROR });
+ this.reportToSentry(error);
+ },
+ },
+ },
+ computed: {
+ variables() {
+ const { id } = this.runner;
+ return {
+ id,
+ ...getPaginationVariables(this.pagination, RUNNER_DETAILS_JOBS_PAGE_SIZE),
+ };
+ },
+ loading() {
+ return this.$apollo.queries.jobs.loading;
+ },
+ },
+ methods: {
+ reportToSentry(error) {
+ captureException({ error, component: this.$options.name });
+ },
+ },
+ I18N_NO_JOBS_FOUND,
+};
+</script>
+
+<template>
+ <div class="gl-pt-3">
+ <gl-skeleton-loading v-if="loading" class="gl-py-5" />
+ <runner-jobs-table v-else-if="jobs.items.length" :jobs="jobs.items" />
+ <p v-else>{{ $options.I18N_NO_JOBS_FOUND }}</p>
+
+ <runner-pagination v-model="pagination" :disabled="loading" :page-info="jobs.pageInfo" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/runner/components/runner_jobs_table.vue b/app/assets/javascripts/runner/components/runner_jobs_table.vue
new file mode 100644
index 00000000000..7817577bab0
--- /dev/null
+++ b/app/assets/javascripts/runner/components/runner_jobs_table.vue
@@ -0,0 +1,95 @@
+<script>
+import { GlTableLite } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
+import RunnerTags from '~/runner/components/runner_tags.vue';
+import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
+import { tableField } from '../utils';
+import LinkCell from './cells/link_cell.vue';
+
+export default {
+ components: {
+ CiBadge,
+ GlTableLite,
+ LinkCell,
+ RunnerTags,
+ TimeAgo,
+ },
+ props: {
+ jobs: {
+ type: Array,
+ required: true,
+ },
+ },
+ methods: {
+ trAttr(job) {
+ if (job?.id) {
+ return { 'data-testid': `job-row-${getIdFromGraphQLId(job.id)}` };
+ }
+ return {};
+ },
+ jobId(job) {
+ return getIdFromGraphQLId(job.id);
+ },
+ jobPath(job) {
+ return job.detailedStatus?.detailsPath;
+ },
+ projectName(job) {
+ return job.pipeline?.project?.name;
+ },
+ projectWebUrl(job) {
+ return job.pipeline?.project?.webUrl;
+ },
+ commitShortSha(job) {
+ return job.shortSha;
+ },
+ commitPath(job) {
+ return job.commitPath;
+ },
+ },
+ fields: [
+ tableField({ key: 'status', label: s__('Job|Status') }),
+ tableField({ key: 'job', label: __('Job') }),
+ tableField({ key: 'project', label: __('Project') }),
+ tableField({ key: 'commit', label: __('Commit') }),
+ tableField({ key: 'finished_at', label: s__('Job|Finished at') }),
+ tableField({ key: 'tags', label: s__('Runners|Tags') }),
+ ],
+};
+</script>
+
+<template>
+ <gl-table-lite
+ :items="jobs"
+ :fields="$options.fields"
+ :tbody-tr-attr="trAttr"
+ primary-key="id"
+ stacked="md"
+ fixed
+ >
+ <template #cell(status)="{ item = {} }">
+ <ci-badge v-if="item.detailedStatus" :status="item.detailedStatus" />
+ </template>
+
+ <template #cell(job)="{ item = {} }">
+ <link-cell :href="jobPath(item)"> #{{ jobId(item) }} </link-cell>
+ </template>
+
+ <template #cell(project)="{ item = {} }">
+ <link-cell :href="projectWebUrl(item)">{{ projectName(item) }}</link-cell>
+ </template>
+
+ <template #cell(commit)="{ item = {} }">
+ <link-cell :href="commitPath(item)"> {{ commitShortSha(item) }}</link-cell>
+ </template>
+
+ <template #cell(tags)="{ item = {} }">
+ <runner-tags :tag-list="item.tags" />
+ </template>
+
+ <template #cell(finished_at)="{ item = {} }">
+ <time-ago v-if="item.finishedAt" :time="item.finishedAt" />
+ </template>
+ </gl-table-lite>
+</template>
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index 45e61768d1e..1544efaaae2 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -4,6 +4,7 @@ export const RUNNER_PAGE_SIZE = 20;
export const RUNNER_JOB_COUNT_LIMIT = 1000;
export const RUNNER_DETAILS_PROJECTS_PAGE_SIZE = 5;
+export const RUNNER_DETAILS_JOBS_PAGE_SIZE = 30;
export const I18N_FETCH_ERROR = s__('Runners|Something went wrong while fetching runner data.');
export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}');
@@ -45,6 +46,7 @@ export const I18N_PAUSED_RUNNER_DESCRIPTION = s__('Runners|Not available to run
export const I18N_ASSIGNED_PROJECTS = s__('Runners|Assigned Projects (%{projectCount})');
export const I18N_NONE = __('None');
+export const I18N_NO_JOBS_FOUND = s__('Runner|This runner has not run any jobs.');
// Styles
diff --git a/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql b/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql
new file mode 100644
index 00000000000..2b1decd3ddd
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql
@@ -0,0 +1,36 @@
+#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+
+query getRunnerJobs($id: CiRunnerID!, $first: Int, $last: Int, $before: String, $after: String) {
+ runner(id: $id) {
+ id
+ projectCount
+ jobs(before: $before, after: $after, first: $first, last: $last) {
+ nodes {
+ id
+ detailedStatus {
+ # fields for `<ci-badge>`
+ id
+ detailsPath
+ group
+ icon
+ text
+ }
+ pipeline {
+ id
+ project {
+ id
+ name
+ webUrl
+ }
+ }
+ shortSha
+ commitPath
+ tags
+ finishedAt
+ }
+ pageInfo {
+ ...PageInfo
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
index ae29fa3a4df..74760bbaa07 100644
--- a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
@@ -8,6 +8,7 @@ fragment RunnerDetailsShared on CiRunner {
ipAddress
description
maximumTimeout
+ jobCount
tagList
createdAt
status(legacyMode: null)