Commit 11271ac4 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '215517-add-dag-endpoint-fe' into 'master'

Add DAG endpoint and graph shell

See merge request gitlab-org/gitlab!32460
parents 28a089b4 43387d80
<script>
import { GlAlert } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
export default {
// eslint-disable-next-line @gitlab/require-i18n-strings
name: 'Dag',
components: {
GlAlert,
},
props: {
graphUrl: {
type: String,
required: false,
default: '',
},
},
data() {
return {
showFailureAlert: false,
};
},
computed: {
shouldDisplayGraph() {
return !this.showFailureAlert;
},
},
mounted() {
const { drawGraph, reportFailure } = this;
if (!this.graphUrl) {
reportFailure();
return;
}
axios
.get(this.graphUrl)
.then(response => {
drawGraph(response.data);
})
.catch(reportFailure);
},
methods: {
drawGraph(data) {
return data;
},
hideAlert() {
this.showFailureAlert = false;
},
reportFailure() {
this.showFailureAlert = true;
},
},
};
</script>
<template>
<div>
<gl-alert v-if="showFailureAlert" variant="danger" @dismiss="hideAlert">
{{ __('We are currently unable to fetch data for this graph.') }}
</gl-alert>
<div v-if="shouldDisplayGraph" data-testid="dag-graph-container">
<!-- graph goes here -->
</div>
</div>
</template>
......@@ -4,6 +4,7 @@ import Translate from '~/vue_shared/translate';
import { __ } from '~/locale';
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import pipelineGraph from './components/graph/graph_component.vue';
import Dag from './components/dag/dag.vue';
import GraphBundleMixin from './mixins/graph_pipeline_bundle_mixin';
import PipelinesMediator from './pipeline_details_mediator';
import pipelineHeader from './components/header_component.vue';
......@@ -144,6 +145,25 @@ const createTestDetails = detailsEndpoint => {
.catch(() => {});
};
const createDagApp = () => {
const el = document.querySelector('#js-pipeline-dag-vue');
const graphUrl = el.dataset?.pipelineDataPath;
// eslint-disable-next-line no-new
new Vue({
el,
components: {
Dag,
},
render(createElement) {
return createElement('dag', {
props: {
graphUrl,
},
});
},
});
};
export default () => {
const { dataset } = document.querySelector('.js-pipeline-details-vue');
const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
......@@ -153,4 +173,5 @@ export default () => {
createPipelineHeaderApp(mediator);
createPipelinesTabs(dataset);
createTestDetails(dataset.testReportsCountEndpoint);
createDagApp();
};
......@@ -6,14 +6,14 @@
%li.js-pipeline-tab-link
= link_to project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do
= _('Pipeline')
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
%span.badge.badge-pill.js-builds-counter= pipeline.total_size
- if dag_pipeline_tab_enabled
%li.js-dag-tab-link
= link_to dag_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-dag', action: 'dag', toggle: 'tab' }, class: 'dag-tab' do
= _('DAG')
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
%span.badge.badge-pill.js-builds-counter= pipeline.total_size
- if @pipeline.failed_builds.present?
%li.js-failures-tab-link
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
......
......@@ -24326,6 +24326,9 @@ msgstr ""
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
msgid "We are currently unable to fetch data for this graph."
msgstr ""
msgid "We could not determine the path to remove the epic"
msgstr ""
......
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import waitForPromises from 'helpers/wait_for_promises';
import { GlAlert } from '@gitlab/ui';
import Dag from '~/pipelines/components/dag/dag.vue';
describe('Pipeline DAG graph', () => {
let wrapper;
let axiosMock;
const getAlert = () => wrapper.find(GlAlert);
const getGraph = () => wrapper.find('[data-testid="dag-graph-container"]');
const dataPath = 'root/test/pipelines/90/dag.json';
const createComponent = (propsData = {}, method = mount) => {
axiosMock = new MockAdapter(axios);
if (wrapper?.destroy) {
wrapper.destroy();
}
wrapper = method(Dag, {
propsData,
data() {
return {
showFailureAlert: false,
};
},
});
};
afterEach(() => {
axiosMock.restore();
wrapper.destroy();
wrapper = null;
});
describe('when there is no dataUrl', () => {
beforeEach(() => {
createComponent({ graphUrl: undefined });
});
it('shows the alert and not the graph', () => {
expect(getAlert().exists()).toBe(true);
expect(getGraph().exists()).toBe(false);
});
});
describe('when there is a dataUrl', () => {
beforeEach(() => {
createComponent({ graphUrl: dataPath });
});
it('shows the graph and not the alert', () => {
expect(getAlert().exists()).toBe(false);
expect(getGraph().exists()).toBe(true);
});
describe('but the data fetch fails', () => {
beforeEach(() => {
axiosMock.onGet(dataPath).replyOnce(500);
createComponent({ graphUrl: dataPath });
});
it('shows the alert and not the graph', () => {
return wrapper.vm
.$nextTick()
.then(waitForPromises)
.then(() => {
expect(getAlert().exists()).toBe(true);
expect(getGraph().exists()).toBe(false);
});
});
});
});
});
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