2018-03-17 18:26:18 +05:30
|
|
|
<script>
|
2022-11-25 23:54:43 +05:30
|
|
|
import { GlBadge, GlPagination, GlSearchBoxByType, GlTab, GlTabs } from '@gitlab/ui';
|
|
|
|
import { debounce } from 'lodash';
|
2022-05-07 20:08:51 +05:30
|
|
|
import { s__, __, sprintf } from '~/locale';
|
|
|
|
import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
|
2022-11-25 23:54:43 +05:30
|
|
|
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
2022-05-07 20:08:51 +05:30
|
|
|
import environmentAppQuery from '../graphql/queries/environment_app.query.graphql';
|
|
|
|
import pollIntervalQuery from '../graphql/queries/poll_interval.query.graphql';
|
|
|
|
import pageInfoQuery from '../graphql/queries/page_info.query.graphql';
|
|
|
|
import environmentToDeleteQuery from '../graphql/queries/environment_to_delete.query.graphql';
|
|
|
|
import environmentToRollbackQuery from '../graphql/queries/environment_to_rollback.query.graphql';
|
|
|
|
import environmentToStopQuery from '../graphql/queries/environment_to_stop.query.graphql';
|
|
|
|
import environmentToChangeCanaryQuery from '../graphql/queries/environment_to_change_canary.query.graphql';
|
|
|
|
import { ENVIRONMENTS_SCOPE } from '../constants';
|
|
|
|
import EnvironmentFolder from './environment_folder.vue';
|
2021-01-03 14:25:43 +05:30
|
|
|
import EnableReviewAppModal from './enable_review_app_modal.vue';
|
2018-12-13 13:39:08 +05:30
|
|
|
import StopEnvironmentModal from './stop_environment_modal.vue';
|
2022-05-07 20:08:51 +05:30
|
|
|
import EnvironmentItem from './new_environment_item.vue';
|
|
|
|
import ConfirmRollbackModal from './confirm_rollback_modal.vue';
|
|
|
|
import DeleteEnvironmentModal from './delete_environment_modal.vue';
|
|
|
|
import CanaryUpdateModal from './canary_update_modal.vue';
|
|
|
|
import EmptyState from './empty_state.vue';
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
export default {
|
|
|
|
components: {
|
2022-05-07 20:08:51 +05:30
|
|
|
DeleteEnvironmentModal,
|
|
|
|
CanaryUpdateModal,
|
2020-03-13 15:44:24 +05:30
|
|
|
ConfirmRollbackModal,
|
2022-05-07 20:08:51 +05:30
|
|
|
EmptyState,
|
|
|
|
EnvironmentFolder,
|
2021-01-03 14:25:43 +05:30
|
|
|
EnableReviewAppModal,
|
2022-05-07 20:08:51 +05:30
|
|
|
EnvironmentItem,
|
|
|
|
StopEnvironmentModal,
|
2021-01-03 14:25:43 +05:30
|
|
|
GlBadge,
|
2022-05-07 20:08:51 +05:30
|
|
|
GlPagination,
|
2022-11-25 23:54:43 +05:30
|
|
|
GlSearchBoxByType,
|
2021-01-03 14:25:43 +05:30
|
|
|
GlTab,
|
|
|
|
GlTabs,
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
apollo: {
|
|
|
|
environmentApp: {
|
|
|
|
query: environmentAppQuery,
|
|
|
|
variables() {
|
|
|
|
return {
|
|
|
|
scope: this.scope,
|
|
|
|
page: this.page ?? 1,
|
2022-11-25 23:54:43 +05:30
|
|
|
search: this.search,
|
2022-05-07 20:08:51 +05:30
|
|
|
};
|
|
|
|
},
|
2022-11-25 23:54:43 +05:30
|
|
|
pollInterval: 3000,
|
2022-05-07 20:08:51 +05:30
|
|
|
},
|
|
|
|
interval: {
|
|
|
|
query: pollIntervalQuery,
|
|
|
|
},
|
|
|
|
pageInfo: {
|
|
|
|
query: pageInfoQuery,
|
|
|
|
},
|
|
|
|
environmentToDelete: {
|
|
|
|
query: environmentToDeleteQuery,
|
2018-03-17 18:26:18 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
environmentToRollback: {
|
|
|
|
query: environmentToRollbackQuery,
|
2018-03-17 18:26:18 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
environmentToStop: {
|
|
|
|
query: environmentToStopQuery,
|
2018-03-17 18:26:18 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
environmentToChangeCanary: {
|
|
|
|
query: environmentToChangeCanaryQuery,
|
|
|
|
},
|
|
|
|
weight: {
|
|
|
|
query: environmentToChangeCanaryQuery,
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
inject: ['newEnvironmentPath', 'canCreateEnvironment', 'helpPagePath'],
|
|
|
|
i18n: {
|
|
|
|
newEnvironmentButtonLabel: s__('Environments|New environment'),
|
|
|
|
reviewAppButtonLabel: s__('Environments|Enable review app'),
|
|
|
|
available: __('Available'),
|
|
|
|
stopped: __('Stopped'),
|
|
|
|
prevPage: __('Go to previous page'),
|
|
|
|
nextPage: __('Go to next page'),
|
|
|
|
next: __('Next'),
|
|
|
|
prev: __('Prev'),
|
|
|
|
goto: (page) => sprintf(__('Go to page %{page}'), { page }),
|
2022-11-25 23:54:43 +05:30
|
|
|
searchPlaceholder: s__('Environments|Search by environment name'),
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
modalId: 'enable-review-app-info',
|
|
|
|
data() {
|
2022-11-25 23:54:43 +05:30
|
|
|
const { page = '1', search = '', scope } = queryToObject(window.location.search);
|
2022-05-07 20:08:51 +05:30
|
|
|
return {
|
|
|
|
interval: undefined,
|
|
|
|
isReviewAppModalVisible: false,
|
|
|
|
page: parseInt(page, 10),
|
|
|
|
pageInfo: {},
|
|
|
|
scope: Object.values(ENVIRONMENTS_SCOPE).includes(scope)
|
|
|
|
? scope
|
|
|
|
: ENVIRONMENTS_SCOPE.AVAILABLE,
|
|
|
|
environmentToDelete: {},
|
|
|
|
environmentToRollback: {},
|
|
|
|
environmentToStop: {},
|
|
|
|
environmentToChangeCanary: {},
|
|
|
|
weight: 0,
|
2022-11-25 23:54:43 +05:30
|
|
|
search,
|
2022-05-07 20:08:51 +05:30
|
|
|
};
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
computed: {
|
|
|
|
canSetupReviewApp() {
|
|
|
|
return this.environmentApp?.reviewApp?.canSetupReviewApp;
|
2020-05-24 23:13:21 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
folders() {
|
|
|
|
return this.environmentApp?.environments?.filter((e) => e.size > 1) ?? [];
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
environments() {
|
|
|
|
return this.environmentApp?.environments?.filter((e) => e.size === 1) ?? [];
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
hasEnvironments() {
|
|
|
|
return this.environments.length > 0 || this.folders.length > 0;
|
|
|
|
},
|
2022-11-25 23:54:43 +05:30
|
|
|
hasSearch() {
|
|
|
|
return Boolean(this.search);
|
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
availableCount() {
|
|
|
|
return this.environmentApp?.availableCount;
|
|
|
|
},
|
|
|
|
addEnvironment() {
|
|
|
|
if (!this.canCreateEnvironment) {
|
|
|
|
return null;
|
|
|
|
}
|
2018-03-17 18:26:18 +05:30
|
|
|
|
2022-05-07 20:08:51 +05:30
|
|
|
return {
|
|
|
|
text: this.$options.i18n.newEnvironmentButtonLabel,
|
|
|
|
attributes: {
|
|
|
|
href: this.newEnvironmentPath,
|
|
|
|
category: 'primary',
|
|
|
|
variant: 'confirm',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
openReviewAppModal() {
|
|
|
|
if (!this.canSetupReviewApp) {
|
|
|
|
return null;
|
2018-12-13 13:39:08 +05:30
|
|
|
}
|
2022-05-07 20:08:51 +05:30
|
|
|
|
|
|
|
return {
|
|
|
|
text: this.$options.i18n.reviewAppButtonLabel,
|
|
|
|
attributes: {
|
|
|
|
category: 'secondary',
|
|
|
|
variant: 'confirm',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
stoppedCount() {
|
|
|
|
return this.environmentApp?.stoppedCount;
|
2018-03-17 18:26:18 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
totalItems() {
|
|
|
|
return this.pageInfo?.total;
|
|
|
|
},
|
|
|
|
itemsPerPage() {
|
|
|
|
return this.pageInfo?.perPage;
|
|
|
|
},
|
|
|
|
},
|
2022-11-25 23:54:43 +05:30
|
|
|
watch: {
|
|
|
|
interval(val) {
|
|
|
|
this.$apollo.queries.environmentApp.stopPolling();
|
|
|
|
this.$apollo.queries.environmentApp.startPolling(val);
|
|
|
|
},
|
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
mounted() {
|
|
|
|
window.addEventListener('popstate', this.syncPageFromQueryParams);
|
2022-11-25 23:54:43 +05:30
|
|
|
window.addEventListener('popstate', this.syncSearchFromQueryParams);
|
2018-12-13 13:39:08 +05:30
|
|
|
},
|
2022-05-07 20:08:51 +05:30
|
|
|
destroyed() {
|
|
|
|
window.removeEventListener('popstate', this.syncPageFromQueryParams);
|
2022-11-25 23:54:43 +05:30
|
|
|
window.removeEventListener('popstate', this.syncSearchFromQueryParams);
|
2022-05-07 20:08:51 +05:30
|
|
|
this.$apollo.queries.environmentApp.stopPolling();
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
showReviewAppModal() {
|
|
|
|
this.isReviewAppModalVisible = true;
|
|
|
|
},
|
|
|
|
setScope(scope) {
|
|
|
|
this.scope = scope;
|
|
|
|
this.moveToPage(1);
|
|
|
|
},
|
|
|
|
movePage(direction) {
|
|
|
|
this.moveToPage(this.pageInfo[`${direction}Page`]);
|
|
|
|
},
|
|
|
|
moveToPage(page) {
|
|
|
|
this.page = page;
|
|
|
|
updateHistory({
|
2022-11-25 23:54:43 +05:30
|
|
|
url: setUrlParams({ page: this.page, scope: this.scope, search: this.search }),
|
2022-05-07 20:08:51 +05:30
|
|
|
title: document.title,
|
|
|
|
});
|
|
|
|
},
|
2022-11-25 23:54:43 +05:30
|
|
|
setSearch: debounce(function setSearch(input) {
|
|
|
|
this.search = input;
|
|
|
|
this.moveToPage(1);
|
|
|
|
}, DEFAULT_DEBOUNCE_AND_THROTTLE_MS),
|
2022-05-07 20:08:51 +05:30
|
|
|
syncPageFromQueryParams() {
|
|
|
|
const { page = '1' } = queryToObject(window.location.search);
|
|
|
|
this.page = parseInt(page, 10);
|
|
|
|
},
|
2022-11-25 23:54:43 +05:30
|
|
|
syncSearchFromQueryParams() {
|
|
|
|
const { search = '' } = queryToObject(window.location.search);
|
|
|
|
this.search = search;
|
|
|
|
},
|
|
|
|
refetchEnvironments() {
|
2022-05-07 20:08:51 +05:30
|
|
|
this.$apollo.queries.environmentApp.refetch();
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ENVIRONMENTS_SCOPE,
|
2018-12-13 13:39:08 +05:30
|
|
|
};
|
2018-03-17 18:26:18 +05:30
|
|
|
</script>
|
|
|
|
<template>
|
2022-05-07 20:08:51 +05:30
|
|
|
<div>
|
|
|
|
<enable-review-app-modal
|
|
|
|
v-if="canSetupReviewApp"
|
|
|
|
v-model="isReviewAppModalVisible"
|
|
|
|
:modal-id="$options.modalId"
|
|
|
|
data-testid="enable-review-app-modal"
|
|
|
|
/>
|
|
|
|
<delete-environment-modal :environment="environmentToDelete" graphql />
|
|
|
|
<stop-environment-modal :environment="environmentToStop" graphql />
|
|
|
|
<confirm-rollback-modal :environment="environmentToRollback" graphql />
|
|
|
|
<canary-update-modal :environment="environmentToChangeCanary" :weight="weight" />
|
|
|
|
<gl-tabs
|
|
|
|
:action-secondary="addEnvironment"
|
|
|
|
:action-primary="openReviewAppModal"
|
|
|
|
sync-active-tab-with-query-params
|
|
|
|
query-param-name="scope"
|
|
|
|
@primary="showReviewAppModal"
|
|
|
|
>
|
|
|
|
<gl-tab
|
|
|
|
:query-param-value="$options.ENVIRONMENTS_SCOPE.AVAILABLE"
|
|
|
|
@click="setScope($options.ENVIRONMENTS_SCOPE.AVAILABLE)"
|
|
|
|
>
|
|
|
|
<template #title>
|
|
|
|
<span>{{ $options.i18n.available }}</span>
|
|
|
|
<gl-badge size="sm" class="gl-tab-counter-badge">
|
|
|
|
{{ availableCount }}
|
|
|
|
</gl-badge>
|
2021-01-03 14:25:43 +05:30
|
|
|
</template>
|
2022-05-07 20:08:51 +05:30
|
|
|
</gl-tab>
|
|
|
|
<gl-tab
|
|
|
|
:query-param-value="$options.ENVIRONMENTS_SCOPE.STOPPED"
|
|
|
|
@click="setScope($options.ENVIRONMENTS_SCOPE.STOPPED)"
|
2021-01-03 14:25:43 +05:30
|
|
|
>
|
2022-05-07 20:08:51 +05:30
|
|
|
<template #title>
|
|
|
|
<span>{{ $options.i18n.stopped }}</span>
|
|
|
|
<gl-badge size="sm" class="gl-tab-counter-badge">
|
|
|
|
{{ stoppedCount }}
|
|
|
|
</gl-badge>
|
2021-01-03 14:25:43 +05:30
|
|
|
</template>
|
2022-05-07 20:08:51 +05:30
|
|
|
</gl-tab>
|
|
|
|
</gl-tabs>
|
2022-11-25 23:54:43 +05:30
|
|
|
<gl-search-box-by-type
|
|
|
|
class="gl-mb-4"
|
|
|
|
:value="search"
|
|
|
|
:placeholder="$options.i18n.searchPlaceholder"
|
|
|
|
@input="setSearch"
|
|
|
|
/>
|
2022-05-07 20:08:51 +05:30
|
|
|
<template v-if="hasEnvironments">
|
|
|
|
<environment-folder
|
|
|
|
v-for="folder in folders"
|
|
|
|
:key="folder.name"
|
|
|
|
class="gl-mb-3"
|
|
|
|
:scope="scope"
|
2022-11-25 23:54:43 +05:30
|
|
|
:search="search"
|
2022-05-07 20:08:51 +05:30
|
|
|
:nested-environment="folder"
|
|
|
|
/>
|
|
|
|
<environment-item
|
|
|
|
v-for="environment in environments"
|
|
|
|
:key="environment.name"
|
|
|
|
class="gl-mb-3 gl-border-gray-100 gl-border-1 gl-border-b-solid"
|
|
|
|
:environment="environment.latest"
|
2022-11-25 23:54:43 +05:30
|
|
|
@change="refetchEnvironments"
|
2021-01-03 14:25:43 +05:30
|
|
|
/>
|
2022-05-07 20:08:51 +05:30
|
|
|
</template>
|
2022-11-25 23:54:43 +05:30
|
|
|
<empty-state
|
|
|
|
v-else-if="!$apollo.queries.environmentApp.loading"
|
|
|
|
:help-path="helpPagePath"
|
|
|
|
:scope="scope"
|
|
|
|
:has-term="hasSearch"
|
|
|
|
/>
|
2022-05-07 20:08:51 +05:30
|
|
|
<gl-pagination
|
|
|
|
align="center"
|
|
|
|
:total-items="totalItems"
|
|
|
|
:per-page="itemsPerPage"
|
|
|
|
:value="page"
|
|
|
|
:next="$options.i18n.next"
|
|
|
|
:prev="$options.i18n.prev"
|
|
|
|
:label-previous-page="$options.prevPage"
|
|
|
|
:label-next-page="$options.nextPage"
|
|
|
|
:label-page="$options.goto"
|
|
|
|
@next="movePage('next')"
|
|
|
|
@previous="movePage('previous')"
|
|
|
|
@input="moveToPage"
|
|
|
|
/>
|
2018-03-17 18:26:18 +05:30
|
|
|
</div>
|
|
|
|
</template>
|