Commit 0972d05c authored by Jose Ivan Vargas's avatar Jose Ivan Vargas Committed by Andrew Fontaine

Remove graphql_pipeline_header feature flag

This removes the graphql_pipeline_header feature
flag and removes the legacy header components
parent 0d2ac3d5
<script>
import { GlLoadingIcon, GlModal, GlModalDirective, GlButton } from '@gitlab/ui';
import ciHeader from '~/vue_shared/components/header_ci_component.vue';
import eventHub from '../event_hub';
import { __ } from '~/locale';
const DELETE_MODAL_ID = 'pipeline-delete-modal';
export default {
name: 'PipelineHeaderSection',
components: {
ciHeader,
GlLoadingIcon,
GlModal,
GlButton,
},
directives: {
GlModal: GlModalDirective,
},
props: {
pipeline: {
type: Object,
required: true,
},
isLoading: {
type: Boolean,
required: true,
},
},
data() {
return {
isCanceling: false,
isRetrying: false,
isDeleting: false,
};
},
computed: {
status() {
return this.pipeline.details && this.pipeline.details.status;
},
shouldRenderContent() {
return !this.isLoading && Object.keys(this.pipeline).length;
},
deleteModalConfirmationText() {
return __(
'Are you sure you want to delete this pipeline? Doing so will expire all pipeline caches and delete all related objects, such as builds, logs, artifacts, and triggers. This action cannot be undone.',
);
},
},
methods: {
cancelPipeline() {
this.isCanceling = true;
eventHub.$emit('headerPostAction', this.pipeline.cancel_path);
},
retryPipeline() {
this.isRetrying = true;
eventHub.$emit('headerPostAction', this.pipeline.retry_path);
},
deletePipeline() {
this.isDeleting = true;
eventHub.$emit('headerDeleteAction', this.pipeline.delete_path);
},
},
DELETE_MODAL_ID,
};
</script>
<template>
<div class="pipeline-header-container">
<ci-header
v-if="shouldRenderContent"
:status="status"
:item-id="pipeline.id"
:time="pipeline.created_at"
:user="pipeline.user"
item-name="Pipeline"
>
<gl-button
v-if="pipeline.retry_path"
:loading="isRetrying"
:disabled="isRetrying"
data-testid="retryButton"
category="secondary"
variant="info"
@click="retryPipeline()"
>
{{ __('Retry') }}
</gl-button>
<gl-button
v-if="pipeline.cancel_path"
:loading="isCanceling"
:disabled="isCanceling"
data-testid="cancelPipeline"
class="gl-ml-3"
category="primary"
variant="danger"
@click="cancelPipeline()"
>
{{ __('Cancel running') }}
</gl-button>
<gl-button
v-if="pipeline.delete_path"
v-gl-modal="$options.DELETE_MODAL_ID"
:loading="isDeleting"
:disabled="isDeleting"
data-testid="deletePipeline"
class="gl-ml-3"
category="secondary"
variant="danger"
>
{{ __('Delete') }}
</gl-button>
</ci-header>
<gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-3 gl-mb-3" />
<gl-modal
:modal-id="$options.DELETE_MODAL_ID"
:title="__('Delete pipeline')"
:ok-title="__('Delete pipeline')"
ok-variant="danger"
@ok="deletePipeline()"
>
<p>
{{ deleteModalConfirmationText }}
</p>
</gl-modal>
</div>
</template>
......@@ -2,12 +2,9 @@ import Vue from 'vue';
import { deprecatedCreateFlash as Flash } from '~/flash';
import Translate from '~/vue_shared/translate';
import { __ } from '~/locale';
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import PipelineGraphLegacy from './components/graph/graph_component_legacy.vue';
import createDagApp from './pipeline_details_dag';
import GraphBundleMixin from './mixins/graph_pipeline_bundle_mixin';
import legacyPipelineHeader from './components/legacy_header_component.vue';
import eventHub from './event_hub';
import TestReports from './components/test_reports/test_reports.vue';
import createTestReportsStore from './stores/test_reports';
import { reportToSentry } from './components/graph/utils';
......@@ -59,58 +56,6 @@ const createLegacyPipelinesDetailApp = (mediator) => {
});
};
const createLegacyPipelineHeaderApp = (mediator) => {
if (!document.querySelector(SELECTORS.PIPELINE_HEADER)) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el: SELECTORS.PIPELINE_HEADER,
components: {
legacyPipelineHeader,
},
data() {
return {
mediator,
};
},
created() {
eventHub.$on('headerPostAction', this.postAction);
eventHub.$on('headerDeleteAction', this.deleteAction);
},
beforeDestroy() {
eventHub.$off('headerPostAction', this.postAction);
eventHub.$off('headerDeleteAction', this.deleteAction);
},
errorCaptured(err, _vm, info) {
reportToSentry('pipeline_details_bundle_legacy', `error: ${err}, info: ${info}`);
},
methods: {
postAction(path) {
this.mediator.service
.postAction(path)
.then(() => this.mediator.refreshPipeline())
.catch(() => Flash(__('An error occurred while making the request.')));
},
deleteAction(path) {
this.mediator.stopPipelinePoll();
this.mediator.service
.deleteAction(path)
.then(({ request }) => redirectTo(setUrlFragment(request.responseURL, 'delete_success')))
.catch(() => Flash(__('An error occurred while deleting the pipeline.')));
},
},
render(createElement) {
return createElement('legacy-pipeline-header', {
props: {
isLoading: this.mediator.state.isLoading,
pipeline: this.mediator.store.state.pipeline,
},
});
},
});
};
const createTestDetails = () => {
const el = document.querySelector(SELECTORS.PIPELINE_TESTS);
const { summaryEndpoint, suiteEndpoint } = el?.dataset || {};
......@@ -140,19 +85,6 @@ export default async function () {
gon.features.graphqlPipelineDetails || gon.features.graphqlPipelineDetailsUsers;
const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS);
let mediator;
if (!gon.features.graphqlPipelineHeader || !canShowNewPipelineDetails) {
try {
const { default: PipelinesMediator } = await import(
/* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator'
);
mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
mediator.fetchPipeline();
} catch {
Flash(__('An error occurred while loading the pipeline.'));
}
}
if (canShowNewPipelineDetails) {
try {
......@@ -166,19 +98,21 @@ export default async function () {
Flash(__('An error occurred while loading the pipeline.'));
}
} else {
const { default: PipelinesMediator } = await import(
/* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator'
);
const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
mediator.fetchPipeline();
createLegacyPipelinesDetailApp(mediator);
}
if (gon.features.graphqlPipelineHeader) {
try {
const { createPipelineHeaderApp } = await import(
/* webpackChunkName: 'createPipelineHeaderApp' */ './pipeline_details_header'
);
createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
} catch {
Flash(__('An error occurred while loading a section of this page.'));
}
} else {
createLegacyPipelineHeaderApp(mediator);
try {
const { createPipelineHeaderApp } = await import(
/* webpackChunkName: 'createPipelineHeaderApp' */ './pipeline_details_header'
);
createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
} catch {
Flash(__('An error occurred while loading a section of this page.'));
}
}
......@@ -14,7 +14,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:pipelines_security_report_summary, project)
push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: true)
push_frontend_feature_flag(:graphql_pipeline_header, project, type: :development, default_enabled: false)
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)
push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml)
push_frontend_feature_flag(:new_pipeline_form_prefilled_vars, project, type: :development, default_enabled: true)
......
---
title: Remove graphql_pipeline_header feature flag
merge_request: 52247
author:
type: other
---
name: graphql_pipeline_header
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39494
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/254235
milestone: '13.5'
type: development
group: group::pipeline authoring
default_enabled: false
......@@ -138,9 +138,8 @@ RSpec.describe 'Commits' do
end
end
context 'when accessing internal project with disallowed access', :js do
context 'when accessing internal project with disallowed access', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/299575' do
before do
stub_feature_flags(graphql_pipeline_header: false)
project.update(
visibility_level: Gitlab::VisibilityLevel::INTERNAL,
public_builds: false)
......
import { shallowMount } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui';
import LegacyHeaderComponent from '~/pipelines/components/legacy_header_component.vue';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
import eventHub from '~/pipelines/event_hub';
describe('Pipeline details header', () => {
let wrapper;
let glModalDirective;
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
const findDeleteModal = () => wrapper.find(GlModal);
const defaultProps = {
pipeline: {
details: {
status: {
group: 'failed',
icon: 'status_failed',
label: 'failed',
text: 'failed',
details_path: 'path',
},
},
id: 123,
created_at: threeWeeksAgo.toISOString(),
user: {
web_url: 'path',
name: 'Foo',
username: 'foobar',
email: 'foo@bar.com',
avatar_url: 'link',
},
retry_path: 'retry',
cancel_path: 'cancel',
delete_path: 'delete',
},
isLoading: false,
};
const createComponent = (props = {}) => {
glModalDirective = jest.fn();
wrapper = shallowMount(LegacyHeaderComponent, {
propsData: {
...props,
},
directives: {
glModal: {
bind(el, { value }) {
glModalDirective(value);
},
},
},
});
};
beforeEach(() => {
jest.spyOn(eventHub, '$emit');
createComponent(defaultProps);
});
afterEach(() => {
eventHub.$off();
wrapper.destroy();
wrapper = null;
});
it('should render provided pipeline info', () => {
expect(wrapper.find(CiHeader).props()).toMatchObject({
status: defaultProps.pipeline.details.status,
itemId: defaultProps.pipeline.id,
time: defaultProps.pipeline.created_at,
user: defaultProps.pipeline.user,
});
});
describe('action buttons', () => {
it('should not trigger eventHub when nothing happens', () => {
expect(eventHub.$emit).not.toHaveBeenCalled();
});
it('should call postAction when retry button action is clicked', () => {
wrapper.find('[data-testid="retryButton"]').vm.$emit('click');
expect(eventHub.$emit).toHaveBeenCalledWith('headerPostAction', 'retry');
});
it('should call postAction when cancel button action is clicked', () => {
wrapper.find('[data-testid="cancelPipeline"]').vm.$emit('click');
expect(eventHub.$emit).toHaveBeenCalledWith('headerPostAction', 'cancel');
});
it('does not show delete modal', () => {
expect(findDeleteModal()).not.toBeVisible();
});
describe('when delete button action is clicked', () => {
it('displays delete modal', () => {
expect(findDeleteModal().props('modalId')).toBe(wrapper.vm.$options.DELETE_MODAL_ID);
expect(glModalDirective).toHaveBeenCalledWith(wrapper.vm.$options.DELETE_MODAL_ID);
});
it('should call delete when modal is submitted', () => {
findDeleteModal().vm.$emit('ok');
expect(eventHub.$emit).toHaveBeenCalledWith('headerDeleteAction', 'delete');
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment