debian-mirror-gitlab/app/assets/javascripts/runner/group_runners/group_runners_app.vue

316 lines
7.9 KiB
Vue
Raw Normal View History

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>