2021-10-27 15:23:28 +05:30
|
|
|
<script>
|
2022-04-04 11:22:00 +05:30
|
|
|
import { GlBadge, GlLink } from '@gitlab/ui';
|
2022-03-02 08:16:31 +05:30
|
|
|
import { createAlert } from '~/flash';
|
2021-11-11 11:23:49 +05:30
|
|
|
import { fetchPolicies } from '~/lib/graphql';
|
|
|
|
import { updateHistory } from '~/lib/utils/url_utility';
|
2022-04-04 11:22:00 +05:30
|
|
|
import { formatNumber } from '~/locale';
|
2021-11-18 22:05:49 +05:30
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
import RegistrationDropdown from '../components/registration/registration_dropdown.vue';
|
2021-11-11 11:23:49 +05:30
|
|
|
import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
|
|
|
|
import RunnerList from '../components/runner_list.vue';
|
2021-11-18 22:05:49 +05:30
|
|
|
import RunnerName from '../components/runner_name.vue';
|
2022-03-02 08:16:31 +05:30
|
|
|
import RunnerStats from '../components/stat/runner_stats.vue';
|
2021-11-11 11:23:49 +05:30
|
|
|
import RunnerPagination from '../components/runner_pagination.vue';
|
2021-12-11 22:18:48 +05:30
|
|
|
import RunnerTypeTabs from '../components/runner_type_tabs.vue';
|
2022-05-07 20:08:51 +05:30
|
|
|
import RunnerActionsCell from '../components/cells/runner_actions_cell.vue';
|
2021-11-18 22:05:49 +05:30
|
|
|
|
2021-11-11 11:23:49 +05:30
|
|
|
import { statusTokenConfig } from '../components/search_tokens/status_token_config';
|
|
|
|
import {
|
|
|
|
GROUP_FILTERED_SEARCH_NAMESPACE,
|
|
|
|
GROUP_TYPE,
|
2022-04-04 11:22:00 +05:30
|
|
|
PROJECT_TYPE,
|
2022-03-02 08:16:31 +05:30
|
|
|
STATUS_ONLINE,
|
|
|
|
STATUS_OFFLINE,
|
|
|
|
STATUS_STALE,
|
2022-05-07 20:08:51 +05:30
|
|
|
I18N_FETCH_ERROR,
|
2021-11-11 11:23:49 +05:30
|
|
|
} from '../constants';
|
2022-05-07 20:08:51 +05:30
|
|
|
import groupRunnersQuery from '../graphql/list/group_runners.query.graphql';
|
|
|
|
import groupRunnersCountQuery from '../graphql/list/group_runners_count.query.graphql';
|
2021-11-11 11:23:49 +05:30
|
|
|
import {
|
|
|
|
fromUrlQueryToSearch,
|
|
|
|
fromSearchToUrl,
|
|
|
|
fromSearchToVariables,
|
|
|
|
} from '../runner_search_utils';
|
|
|
|
import { captureException } from '../sentry_utils';
|
2021-10-27 15:23:28 +05:30
|
|
|
|
2022-03-02 08:16:31 +05:30
|
|
|
const runnersCountSmartQuery = {
|
2022-05-07 20:08:51 +05:30
|
|
|
query: groupRunnersCountQuery,
|
2022-03-02 08:16:31 +05:30
|
|
|
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
|
|
|
update(data) {
|
|
|
|
return data?.group?.runners?.count;
|
|
|
|
},
|
|
|
|
error(error) {
|
|
|
|
this.reportToSentry(error);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
export default {
|
2021-11-11 11:23:49 +05:30
|
|
|
name: 'GroupRunnersApp',
|
2021-10-27 15:23:28 +05:30
|
|
|
components: {
|
2022-04-04 11:22:00 +05:30
|
|
|
GlBadge,
|
2021-11-18 22:05:49 +05:30
|
|
|
GlLink,
|
2021-12-11 22:18:48 +05:30
|
|
|
RegistrationDropdown,
|
2021-11-11 11:23:49 +05:30
|
|
|
RunnerFilteredSearchBar,
|
|
|
|
RunnerList,
|
2021-11-18 22:05:49 +05:30
|
|
|
RunnerName,
|
2022-03-02 08:16:31 +05:30
|
|
|
RunnerStats,
|
2021-11-11 11:23:49 +05:30
|
|
|
RunnerPagination,
|
2021-12-11 22:18:48 +05:30
|
|
|
RunnerTypeTabs,
|
2022-05-07 20:08:51 +05:30
|
|
|
RunnerActionsCell,
|
2021-10-27 15:23:28 +05:30
|
|
|
},
|
|
|
|
props: {
|
|
|
|
registrationToken: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
2021-11-11 11:23:49 +05:30
|
|
|
groupFullPath: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
groupRunnersLimitedCount: {
|
|
|
|
type: Number,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
search: fromUrlQueryToSearch(),
|
|
|
|
runners: {
|
|
|
|
items: [],
|
2022-05-07 20:08:51 +05:30
|
|
|
urlsById: {},
|
2021-11-11 11:23:49 +05:30
|
|
|
pageInfo: {},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
apollo: {
|
|
|
|
runners: {
|
2022-05-07 20:08:51 +05:30
|
|
|
query: groupRunnersQuery,
|
2021-11-11 11:23:49 +05:30
|
|
|
// Runners can be updated by users directly in this list.
|
|
|
|
// A "cache and network" policy prevents outdated filtered
|
|
|
|
// results.
|
|
|
|
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
|
|
|
|
variables() {
|
|
|
|
return this.variables;
|
|
|
|
},
|
|
|
|
update(data) {
|
2022-05-07 20:08:51 +05:30
|
|
|
const { edges = [], pageInfo = {} } = data?.group?.runners || {};
|
|
|
|
|
|
|
|
const items = [];
|
|
|
|
const urlsById = {};
|
|
|
|
|
|
|
|
edges.forEach(({ node, webUrl, editUrl }) => {
|
|
|
|
items.push(node);
|
|
|
|
urlsById[node.id] = {
|
|
|
|
web: webUrl,
|
|
|
|
edit: editUrl,
|
|
|
|
};
|
|
|
|
});
|
2021-11-18 22:05:49 +05:30
|
|
|
|
2021-11-11 11:23:49 +05:30
|
|
|
return {
|
2022-05-07 20:08:51 +05:30
|
|
|
items,
|
|
|
|
urlsById,
|
|
|
|
pageInfo,
|
2021-11-11 11:23:49 +05:30
|
|
|
};
|
|
|
|
},
|
|
|
|
error(error) {
|
2022-03-02 08:16:31 +05:30
|
|
|
createAlert({ message: I18N_FETCH_ERROR });
|
2021-11-11 11:23:49 +05:30
|
|
|
|
|
|
|
this.reportToSentry(error);
|
|
|
|
},
|
|
|
|
},
|
2022-03-02 08:16:31 +05:30
|
|
|
onlineRunnersTotal: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
groupFullPath: this.groupFullPath,
|
|
|
|
status: STATUS_ONLINE,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
offlineRunnersTotal: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
groupFullPath: this.groupFullPath,
|
|
|
|
status: STATUS_OFFLINE,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
staleRunnersTotal: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
groupFullPath: this.groupFullPath,
|
|
|
|
status: STATUS_STALE,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
2022-04-04 11:22:00 +05:30
|
|
|
allRunnersCount: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
...this.countVariables,
|
|
|
|
type: null,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
groupRunnersCount: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
...this.countVariables,
|
|
|
|
type: GROUP_TYPE,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
projectRunnersCount: {
|
|
|
|
...runnersCountSmartQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
...this.countVariables,
|
|
|
|
type: PROJECT_TYPE,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
2021-11-11 11:23:49 +05:30
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
...fromSearchToVariables(this.search),
|
|
|
|
groupFullPath: this.groupFullPath,
|
|
|
|
};
|
|
|
|
},
|
2022-04-04 11:22:00 +05:30
|
|
|
countVariables() {
|
|
|
|
// Exclude pagination variables, leave only filters variables
|
|
|
|
const { sort, before, last, after, first, ...countVariables } = this.variables;
|
|
|
|
return countVariables;
|
|
|
|
},
|
2021-11-11 11:23:49 +05:30
|
|
|
runnersLoading() {
|
|
|
|
return this.$apollo.queries.runners.loading;
|
|
|
|
},
|
|
|
|
noRunnersFound() {
|
|
|
|
return !this.runnersLoading && !this.runners.items.length;
|
|
|
|
},
|
|
|
|
searchTokens() {
|
2021-12-11 22:18:48 +05:30
|
|
|
return [statusTokenConfig];
|
2021-11-11 11:23:49 +05:30
|
|
|
},
|
|
|
|
filteredSearchNamespace() {
|
|
|
|
return `${GROUP_FILTERED_SEARCH_NAMESPACE}/${this.groupFullPath}`;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
search: {
|
|
|
|
deep: true,
|
|
|
|
handler() {
|
|
|
|
// TODO Implement back button reponse using onpopstate
|
2022-05-07 20:08:51 +05:30
|
|
|
// See https://gitlab.com/gitlab-org/gitlab/-/issues/333804
|
2021-11-11 11:23:49 +05:30
|
|
|
updateHistory({
|
|
|
|
url: fromSearchToUrl(this.search),
|
|
|
|
title: document.title,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
errorCaptured(error) {
|
|
|
|
this.reportToSentry(error);
|
|
|
|
},
|
|
|
|
methods: {
|
2022-04-04 11:22:00 +05:30
|
|
|
tabCount({ runnerType }) {
|
|
|
|
let count;
|
|
|
|
switch (runnerType) {
|
|
|
|
case null:
|
|
|
|
count = this.allRunnersCount;
|
|
|
|
break;
|
|
|
|
case GROUP_TYPE:
|
|
|
|
count = this.groupRunnersCount;
|
|
|
|
break;
|
|
|
|
case PROJECT_TYPE:
|
|
|
|
count = this.projectRunnersCount;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (typeof count === 'number') {
|
|
|
|
return formatNumber(count);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
webUrl(runner) {
|
|
|
|
return this.runners.urlsById[runner.id]?.web;
|
|
|
|
},
|
|
|
|
editUrl(runner) {
|
|
|
|
return this.runners.urlsById[runner.id]?.edit;
|
|
|
|
},
|
|
|
|
onDeleted({ message }) {
|
|
|
|
this.$root.$toast?.show(message);
|
|
|
|
this.$apollo.queries.runners.refetch();
|
|
|
|
},
|
2021-11-11 11:23:49 +05:30
|
|
|
reportToSentry(error) {
|
|
|
|
captureException({ error, component: this.$options.name });
|
|
|
|
},
|
2021-10-27 15:23:28 +05:30
|
|
|
},
|
2022-04-04 11:22:00 +05:30
|
|
|
TABS_RUNNER_TYPES: [GROUP_TYPE, PROJECT_TYPE],
|
2021-10-27 15:23:28 +05:30
|
|
|
GROUP_TYPE,
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div>
|
2022-03-02 08:16:31 +05:30
|
|
|
<runner-stats
|
|
|
|
:online-runners-count="onlineRunnersTotal"
|
|
|
|
:offline-runners-count="offlineRunnersTotal"
|
|
|
|
:stale-runners-count="staleRunnersTotal"
|
|
|
|
/>
|
2022-01-26 12:08:38 +05:30
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
<div class="gl-display-flex gl-align-items-center">
|
|
|
|
<runner-type-tabs
|
|
|
|
v-model="search"
|
2022-04-04 11:22:00 +05:30
|
|
|
:runner-types="$options.TABS_RUNNER_TYPES"
|
2021-12-11 22:18:48 +05:30
|
|
|
content-class="gl-display-none"
|
|
|
|
nav-class="gl-border-none!"
|
2022-04-04 11:22:00 +05:30
|
|
|
>
|
|
|
|
<template #title="{ tab }">
|
|
|
|
{{ tab.title }}
|
|
|
|
<gl-badge v-if="tabCount(tab)" class="gl-ml-1" size="sm">
|
|
|
|
{{ tabCount(tab) }}
|
|
|
|
</gl-badge>
|
|
|
|
</template>
|
|
|
|
</runner-type-tabs>
|
2021-12-11 22:18:48 +05:30
|
|
|
|
|
|
|
<registration-dropdown
|
|
|
|
class="gl-ml-auto"
|
|
|
|
:registration-token="registrationToken"
|
|
|
|
:type="$options.GROUP_TYPE"
|
|
|
|
right
|
|
|
|
/>
|
|
|
|
</div>
|
2021-11-11 11:23:49 +05:30
|
|
|
|
|
|
|
<runner-filtered-search-bar
|
|
|
|
v-model="search"
|
|
|
|
:tokens="searchTokens"
|
|
|
|
:namespace="filteredSearchNamespace"
|
2022-01-26 12:08:38 +05:30
|
|
|
/>
|
2021-11-11 11:23:49 +05:30
|
|
|
|
|
|
|
<div v-if="noRunnersFound" class="gl-text-center gl-p-5">
|
|
|
|
{{ __('No runners found') }}
|
|
|
|
</div>
|
|
|
|
<template v-else>
|
2021-11-18 22:05:49 +05:30
|
|
|
<runner-list :runners="runners.items" :loading="runnersLoading">
|
2022-05-07 20:08:51 +05:30
|
|
|
<template #runner-name="{ runner }">
|
|
|
|
<gl-link :href="webUrl(runner)">
|
2021-11-18 22:05:49 +05:30
|
|
|
<runner-name :runner="runner" />
|
|
|
|
</gl-link>
|
|
|
|
</template>
|
2022-05-07 20:08:51 +05:30
|
|
|
<template #runner-actions-cell="{ runner }">
|
|
|
|
<runner-actions-cell :runner="runner" :edit-url="editUrl(runner)" @deleted="onDeleted" />
|
|
|
|
</template>
|
2021-11-18 22:05:49 +05:30
|
|
|
</runner-list>
|
2022-05-07 20:08:51 +05:30
|
|
|
<runner-pagination
|
|
|
|
v-model="search.pagination"
|
|
|
|
class="gl-mt-3"
|
|
|
|
:page-info="runners.pageInfo"
|
|
|
|
/>
|
2021-11-11 11:23:49 +05:30
|
|
|
</template>
|
2021-10-27 15:23:28 +05:30
|
|
|
</div>
|
|
|
|
</template>
|