summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/runner/components/runner_projects.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/runner/components/runner_projects.vue')
-rw-r--r--app/assets/javascripts/runner/components/runner_projects.vue111
1 files changed, 111 insertions, 0 deletions
diff --git a/app/assets/javascripts/runner/components/runner_projects.vue b/app/assets/javascripts/runner/components/runner_projects.vue
new file mode 100644
index 00000000000..c4065a24ff2
--- /dev/null
+++ b/app/assets/javascripts/runner/components/runner_projects.vue
@@ -0,0 +1,111 @@
+<script>
+import { GlSkeletonLoading } from '@gitlab/ui';
+import { sprintf, formatNumber } from '~/locale';
+import { createAlert } from '~/flash';
+import getRunnerProjectsQuery from '../graphql/get_runner_projects.query.graphql';
+import {
+ I18N_ASSIGNED_PROJECTS,
+ I18N_NONE,
+ I18N_FETCH_ERROR,
+ RUNNER_DETAILS_PROJECTS_PAGE_SIZE,
+} from '../constants';
+import { getPaginationVariables } from '../utils';
+import { captureException } from '../sentry_utils';
+import RunnerAssignedItem from './runner_assigned_item.vue';
+import RunnerPagination from './runner_pagination.vue';
+
+export default {
+ name: 'RunnerProjects',
+ components: {
+ GlSkeletonLoading,
+ RunnerAssignedItem,
+ RunnerPagination,
+ },
+ props: {
+ runner: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ projects: {
+ items: [],
+ pageInfo: {},
+ count: 0,
+ },
+ pagination: {
+ page: 1,
+ },
+ };
+ },
+ apollo: {
+ projects: {
+ query: getRunnerProjectsQuery,
+ variables() {
+ return this.variables;
+ },
+ update(data) {
+ const { runner } = data;
+ return {
+ count: runner?.projectCount || 0,
+ items: runner?.projects?.nodes || [],
+ pageInfo: runner?.projects?.pageInfo || {},
+ };
+ },
+ error(error) {
+ createAlert({ message: I18N_FETCH_ERROR });
+
+ this.reportToSentry(error);
+ },
+ },
+ },
+ computed: {
+ variables() {
+ const { id } = this.runner;
+ return {
+ id,
+ ...getPaginationVariables(this.pagination, RUNNER_DETAILS_PROJECTS_PAGE_SIZE),
+ };
+ },
+ loading() {
+ return this.$apollo.queries.projects.loading;
+ },
+ heading() {
+ return sprintf(I18N_ASSIGNED_PROJECTS, {
+ projectCount: formatNumber(this.projects.count),
+ });
+ },
+ },
+ methods: {
+ reportToSentry(error) {
+ captureException({ error, component: this.$options.name });
+ },
+ },
+ I18N_NONE,
+};
+</script>
+
+<template>
+ <div class="gl-border-t-gray-100 gl-border-t-1 gl-border-t-solid">
+ <h3 class="gl-font-lg gl-mt-5 gl-mb-0">
+ {{ heading }}
+ </h3>
+
+ <gl-skeleton-loading v-if="loading" class="gl-py-5" />
+ <template v-else-if="projects.items.length">
+ <runner-assigned-item
+ v-for="(project, i) in projects.items"
+ :key="project.id"
+ :class="{ 'gl-border-t-gray-100 gl-border-t-1 gl-border-t-solid': i !== 0 }"
+ :href="project.webUrl"
+ :name="project.name"
+ :full-name="project.nameWithNamespace"
+ :avatar-url="project.avatarUrl"
+ />
+ </template>
+ <span v-else class="gl-text-gray-500">{{ $options.I18N_NONE }}</span>
+
+ <runner-pagination v-model="pagination" :disabled="loading" :page-info="projects.pageInfo" />
+ </div>
+</template>