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:
Diffstat (limited to 'app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue')
-rw-r--r--app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue256
1 files changed, 256 insertions, 0 deletions
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue
new file mode 100644
index 00000000000..fe16cb7a92e
--- /dev/null
+++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue
@@ -0,0 +1,256 @@
+<script>
+import { GlAlert, GlBadge, GlButton, GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui';
+import { s__, sprintf } from '~/locale';
+import { limitedCounterWithDelimiter } from '~/lib/utils/text_utility';
+import { queryToObject } from '~/lib/utils/url_utility';
+import deletePipelineScheduleMutation from '../graphql/mutations/delete_pipeline_schedule.mutation.graphql';
+import takeOwnershipMutation from '../graphql/mutations/take_ownership.mutation.graphql';
+import getPipelineSchedulesQuery from '../graphql/queries/get_pipeline_schedules.query.graphql';
+import PipelineSchedulesTable from './table/pipeline_schedules_table.vue';
+import TakeOwnershipModal from './take_ownership_modal.vue';
+import DeletePipelineScheduleModal from './delete_pipeline_schedule_modal.vue';
+
+export default {
+ i18n: {
+ schedulesFetchError: s__('PipelineSchedules|There was a problem fetching pipeline schedules.'),
+ scheduleDeleteError: s__(
+ 'PipelineSchedules|There was a problem deleting the pipeline schedule.',
+ ),
+ takeOwnershipError: s__(
+ 'PipelineSchedules|There was a problem taking ownership of the pipeline schedule.',
+ ),
+ newSchedule: s__('PipelineSchedules|New schedule'),
+ deleteSuccess: s__('PipelineSchedules|Pipeline schedule successfully deleted.'),
+ },
+ components: {
+ DeletePipelineScheduleModal,
+ GlAlert,
+ GlBadge,
+ GlButton,
+ GlLoadingIcon,
+ GlTabs,
+ GlTab,
+ PipelineSchedulesTable,
+ TakeOwnershipModal,
+ },
+ inject: {
+ fullPath: {
+ default: '',
+ },
+ },
+ apollo: {
+ schedules: {
+ query: getPipelineSchedulesQuery,
+ variables() {
+ return {
+ projectPath: this.fullPath,
+ status: this.scope,
+ };
+ },
+ update(data) {
+ const { pipelineSchedules: { nodes: list = [], count } = {} } = data.project || {};
+
+ return {
+ list,
+ count,
+ };
+ },
+ error() {
+ this.reportError(this.$options.i18n.schedulesFetchError);
+ },
+ },
+ },
+ data() {
+ const { scope } = queryToObject(window.location.search);
+ return {
+ schedules: {
+ list: [],
+ },
+ scope,
+ hasError: false,
+ errorMessage: '',
+ scheduleId: null,
+ showDeleteModal: false,
+ showTakeOwnershipModal: false,
+ count: 0,
+ };
+ },
+ computed: {
+ isLoading() {
+ return this.$apollo.queries.schedules.loading;
+ },
+ schedulesCount() {
+ return this.schedules.count;
+ },
+ tabs() {
+ return [
+ {
+ text: s__('PipelineSchedules|All'),
+ count: limitedCounterWithDelimiter(this.count),
+ scope: null,
+ showBadge: true,
+ attrs: { 'data-testid': 'pipeline-schedules-all-tab' },
+ },
+ {
+ text: s__('PipelineSchedules|Active'),
+ scope: 'ACTIVE',
+ showBadge: false,
+ attrs: { 'data-testid': 'pipeline-schedules-active-tab' },
+ },
+ {
+ text: s__('PipelineSchedules|Inactive'),
+ scope: 'INACTIVE',
+ showBadge: false,
+ attrs: { 'data-testid': 'pipeline-schedules-inactive-tab' },
+ },
+ ];
+ },
+ },
+ watch: {
+ // this watcher ensures that the count on the all tab
+ // is not updated when switching to other tabs
+ schedulesCount(newCount) {
+ if (!this.scope) {
+ this.count = newCount;
+ }
+ },
+ },
+ methods: {
+ reportError(error) {
+ this.hasError = true;
+ this.errorMessage = error;
+ },
+ setDeleteModal(id) {
+ this.showDeleteModal = true;
+ this.scheduleId = id;
+ },
+ setTakeOwnershipModal(id) {
+ this.showTakeOwnershipModal = true;
+ this.scheduleId = id;
+ },
+ hideModal() {
+ this.showDeleteModal = false;
+ this.showTakeOwnershipModal = false;
+ this.scheduleId = null;
+ },
+ async deleteSchedule() {
+ try {
+ const {
+ data: {
+ pipelineScheduleDelete: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: deletePipelineScheduleMutation,
+ variables: { id: this.scheduleId },
+ });
+
+ if (errors.length > 0) {
+ throw new Error();
+ } else {
+ this.$apollo.queries.schedules.refetch();
+ this.$toast.show(this.$options.i18n.deleteSuccess);
+ }
+ } catch {
+ this.reportError(this.$options.i18n.scheduleDeleteError);
+ }
+ },
+ async takeOwnership() {
+ try {
+ const {
+ data: {
+ pipelineScheduleTakeOwnership: { pipelineSchedule, errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: takeOwnershipMutation,
+ variables: { id: this.scheduleId },
+ });
+
+ if (errors.length > 0) {
+ throw new Error();
+ } else {
+ this.$apollo.queries.schedules.refetch();
+
+ if (pipelineSchedule?.owner?.name) {
+ const toastMsg = sprintf(
+ s__('PipelineSchedules|Successfully taken ownership from %{owner}.'),
+ {
+ owner: pipelineSchedule.owner.name,
+ },
+ );
+
+ this.$toast.show(toastMsg);
+ }
+ }
+ } catch {
+ this.reportError(this.$options.i18n.takeOwnershipError);
+ }
+ },
+ fetchPipelineSchedulesByStatus(scope) {
+ this.scope = scope;
+ this.$apollo.queries.schedules.refetch();
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-alert v-if="hasError" class="gl-mb-2" variant="danger" @dismiss="hasError = false">
+ {{ errorMessage }}
+ </gl-alert>
+
+ <template v-else>
+ <gl-tabs
+ sync-active-tab-with-query-params
+ query-param-name="scope"
+ nav-class="gl-flex-grow-1 gl-align-items-center"
+ >
+ <gl-tab
+ v-for="tab in tabs"
+ :key="tab.text"
+ :title-link-attributes="tab.attrs"
+ :query-param-value="tab.scope"
+ @click="fetchPipelineSchedulesByStatus(tab.scope)"
+ >
+ <template #title>
+ <span>{{ tab.text }}</span>
+
+ <template v-if="tab.showBadge">
+ <gl-loading-icon v-if="tab.scope === scope && isLoading" class="gl-ml-2" />
+
+ <gl-badge v-else-if="tab.count" size="sm" class="gl-tab-counter-badge">
+ {{ tab.count }}
+ </gl-badge>
+ </template>
+ </template>
+
+ <gl-loading-icon v-if="isLoading" size="lg" />
+ <pipeline-schedules-table
+ v-else
+ :schedules="schedules.list"
+ @showTakeOwnershipModal="setTakeOwnershipModal"
+ @showDeleteModal="setDeleteModal"
+ />
+ </gl-tab>
+
+ <template #tabs-end>
+ <gl-button variant="confirm" class="gl-ml-auto" data-testid="new-schedule-button">
+ {{ $options.i18n.newSchedule }}
+ </gl-button>
+ </template>
+ </gl-tabs>
+
+ <take-ownership-modal
+ :visible="showTakeOwnershipModal"
+ @takeOwnership="takeOwnership"
+ @hideModal="hideModal"
+ />
+
+ <delete-pipeline-schedule-modal
+ :visible="showDeleteModal"
+ @deleteSchedule="deleteSchedule"
+ @hideModal="hideModal"
+ />
+ </template>
+ </div>
+</template>