Skip to content
Snippets Groups Projects
Unverified Commit eb2de72c authored by Filipa Lacerda's avatar Filipa Lacerda
Browse files

Prettifies pipeline's javascript code

parent 07de43a7
No related branches found
No related tags found
1 merge request!10495Merge Requests - Assignee
Showing
with 824 additions and 817 deletions
<script>
export default {
name: 'PipelinesSvgState',
props: {
svgPath: {
type: String,
required: true,
},
export default {
name: 'PipelinesSvgState',
props: {
svgPath: {
type: String,
required: true,
},
 
message: {
type: String,
required: true,
},
message: {
type: String,
required: true,
},
};
},
};
</script>
 
<template>
Loading
Loading
<script>
export default {
name: 'PipelinesEmptyState',
props: {
helpPagePath: {
type: String,
required: true,
},
emptyStateSvgPath: {
type: String,
required: true,
},
canSetCi: {
type: Boolean,
required: true,
},
export default {
name: 'PipelinesEmptyState',
props: {
helpPagePath: {
type: String,
required: true,
},
};
emptyStateSvgPath: {
type: String,
required: true,
},
canSetCi: {
type: Boolean,
required: true,
},
},
};
</script>
<template>
<div class="row empty-state js-empty-state">
Loading
Loading
Loading
Loading
@@ -41,7 +41,6 @@ export default {
type: String,
required: true,
},
},
data() {
return {
Loading
Loading
@@ -67,7 +66,8 @@ export default {
 
this.isDisabled = true;
 
axios.post(`${this.link}.json`)
axios
.post(`${this.link}.json`)
.then(() => {
this.isDisabled = false;
this.$emit('pipelineActionRequestComplete');
Loading
Loading
<script>
import ciIcon from '../../../vue_shared/components/ci_icon.vue';
import ciIcon from '../../../vue_shared/components/ci_icon.vue';
 
/**
* Component that renders both the CI icon status and the job name.
* Used in
* - Badge component
* - Dropdown badge components
*/
export default {
components: {
ciIcon,
/**
* Component that renders both the CI icon status and the job name.
* Used in
* - Badge component
* - Dropdown badge components
*/
export default {
components: {
ciIcon,
},
props: {
name: {
type: String,
required: true,
},
props: {
name: {
type: String,
required: true,
},
 
status: {
type: Object,
required: true,
},
status: {
type: Object,
required: true,
},
};
},
};
</script>
<template>
<span class="ci-job-name-component">
Loading
Loading
<script>
import ciHeader from '../../vue_shared/components/header_ci_component.vue';
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import ciHeader from '../../vue_shared/components/header_ci_component.vue';
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
 
export default {
name: 'PipelineHeaderSection',
components: {
ciHeader,
loadingIcon,
export default {
name: 'PipelineHeaderSection',
components: {
ciHeader,
loadingIcon,
},
props: {
pipeline: {
type: Object,
required: true,
},
props: {
pipeline: {
type: Object,
required: true,
},
isLoading: {
type: Boolean,
required: true,
},
},
data() {
return {
actions: this.getActions(),
};
isLoading: {
type: Boolean,
required: true,
},
},
data() {
return {
actions: this.getActions(),
};
},
 
computed: {
status() {
return this.pipeline.details && this.pipeline.details.status;
},
shouldRenderContent() {
return !this.isLoading && Object.keys(this.pipeline).length;
},
computed: {
status() {
return this.pipeline.details && this.pipeline.details.status;
},
shouldRenderContent() {
return !this.isLoading && Object.keys(this.pipeline).length;
},
},
 
watch: {
pipeline() {
this.actions = this.getActions();
},
watch: {
pipeline() {
this.actions = this.getActions();
},
},
 
methods: {
postAction(action) {
const index = this.actions.indexOf(action);
methods: {
postAction(action) {
const index = this.actions.indexOf(action);
 
this.$set(this.actions[index], 'isLoading', true);
this.$set(this.actions[index], 'isLoading', true);
 
eventHub.$emit('headerPostAction', action);
},
eventHub.$emit('headerPostAction', action);
},
 
getActions() {
const actions = [];
getActions() {
const actions = [];
 
if (this.pipeline.retry_path) {
actions.push({
label: 'Retry',
path: this.pipeline.retry_path,
cssClass: 'js-retry-button btn btn-inverted-secondary',
type: 'button',
isLoading: false,
});
}
if (this.pipeline.retry_path) {
actions.push({
label: 'Retry',
path: this.pipeline.retry_path,
cssClass: 'js-retry-button btn btn-inverted-secondary',
type: 'button',
isLoading: false,
});
}
 
if (this.pipeline.cancel_path) {
actions.push({
label: 'Cancel running',
path: this.pipeline.cancel_path,
cssClass: 'js-btn-cancel-pipeline btn btn-danger',
type: 'button',
isLoading: false,
});
}
if (this.pipeline.cancel_path) {
actions.push({
label: 'Cancel running',
path: this.pipeline.cancel_path,
cssClass: 'js-btn-cancel-pipeline btn btn-danger',
type: 'button',
isLoading: false,
});
}
 
return actions;
},
return actions;
},
};
},
};
</script>
<template>
<div class="pipeline-header-container">
Loading
Loading
<script>
import LoadingButton from '../../vue_shared/components/loading_button.vue';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
 
export default {
name: 'PipelineNavControls',
components: {
LoadingButton,
export default {
name: 'PipelineNavControls',
components: {
LoadingButton,
},
props: {
newPipelinePath: {
type: String,
required: false,
default: null,
},
props: {
newPipelinePath: {
type: String,
required: false,
default: null,
},
 
resetCachePath: {
type: String,
required: false,
default: null,
},
resetCachePath: {
type: String,
required: false,
default: null,
},
 
ciLintPath: {
type: String,
required: false,
default: null,
},
ciLintPath: {
type: String,
required: false,
default: null,
},
 
isResetCacheButtonLoading: {
type: Boolean,
required: false,
default: false,
},
isResetCacheButtonLoading: {
type: Boolean,
required: false,
default: false,
},
methods: {
onClickResetCache() {
this.$emit('resetRunnersCache', this.resetCachePath);
},
},
methods: {
onClickResetCache() {
this.$emit('resetRunnersCache', this.resetCachePath);
},
};
},
};
</script>
<template>
<div class="nav-controls">
Loading
Loading
<script>
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import tooltip from '../../vue_shared/directives/tooltip';
import popover from '../../vue_shared/directives/popover';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import tooltip from '../../vue_shared/directives/tooltip';
import popover from '../../vue_shared/directives/popover';
 
export default {
components: {
userAvatarLink,
export default {
components: {
userAvatarLink,
},
directives: {
tooltip,
popover,
},
props: {
pipeline: {
type: Object,
required: true,
},
directives: {
tooltip,
popover,
autoDevopsHelpPath: {
type: String,
required: true,
},
props: {
pipeline: {
type: Object,
required: true,
},
autoDevopsHelpPath: {
type: String,
required: true,
},
},
computed: {
user() {
return this.pipeline.user;
},
computed: {
user() {
return this.pipeline.user;
},
popoverOptions() {
return {
html: true,
trigger: 'focus',
placement: 'top',
title: `<div class="autodevops-title">
popoverOptions() {
return {
html: true,
trigger: 'focus',
placement: 'top',
title: `<div class="autodevops-title">
This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b>
</div>`,
content: `<a
content: `<a
class="autodevops-link"
href="${this.autoDevopsHelpPath}"
target="_blank"
rel="noopener noreferrer nofollow">
Learn more about Auto DevOps
</a>`,
};
},
};
},
};
},
};
</script>
<template>
<div class="table-section section-15 d-none d-sm-none d-md-block pipeline-tags">
Loading
Loading
<script>
import _ from 'underscore';
import { __, sprintf, s__ } from '../../locale';
import createFlash from '../../flash';
import PipelinesService from '../services/pipelines_service';
import pipelinesMixin from '../mixins/pipelines';
import TablePagination from '../../vue_shared/components/table_pagination.vue';
import NavigationTabs from '../../vue_shared/components/navigation_tabs.vue';
import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
import _ from 'underscore';
import { __, sprintf, s__ } from '../../locale';
import createFlash from '../../flash';
import PipelinesService from '../services/pipelines_service';
import pipelinesMixin from '../mixins/pipelines';
import TablePagination from '../../vue_shared/components/table_pagination.vue';
import NavigationTabs from '../../vue_shared/components/navigation_tabs.vue';
import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '../../lib/utils/common_utils';
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
 
export default {
components: {
TablePagination,
NavigationTabs,
NavigationControls,
export default {
components: {
TablePagination,
NavigationTabs,
NavigationControls,
},
mixins: [pipelinesMixin, CIPaginationMixin],
props: {
store: {
type: Object,
required: true,
},
mixins: [pipelinesMixin, CIPaginationMixin],
props: {
store: {
type: Object,
required: true,
},
// Can be rendered in 3 different places, with some visual differences
// Accepts root | child
// `root` -> main view
// `child` -> rendered inside MR or Commit View
viewType: {
type: String,
required: false,
default: 'root',
},
endpoint: {
type: String,
required: true,
},
helpPagePath: {
type: String,
required: true,
},
emptyStateSvgPath: {
type: String,
required: true,
},
errorStateSvgPath: {
type: String,
required: true,
},
noPipelinesSvgPath: {
type: String,
required: true,
},
autoDevopsPath: {
type: String,
required: true,
},
hasGitlabCi: {
type: Boolean,
required: true,
},
canCreatePipeline: {
type: Boolean,
required: true,
},
ciLintPath: {
type: String,
required: false,
default: null,
},
resetCachePath: {
type: String,
required: false,
default: null,
},
newPipelinePath: {
type: String,
required: false,
default: null,
},
// Can be rendered in 3 different places, with some visual differences
// Accepts root | child
// `root` -> main view
// `child` -> rendered inside MR or Commit View
viewType: {
type: String,
required: false,
default: 'root',
},
data() {
return {
// Start with loading state to avoid a glitch when the empty state will be rendered
isLoading: true,
state: this.store.state,
scope: getParameterByName('scope') || 'all',
page: getParameterByName('page') || '1',
requestData: {},
isResetCacheButtonLoading: false,
};
endpoint: {
type: String,
required: true,
},
stateMap: {
// with tabs
loading: 'loading',
tableList: 'tableList',
error: 'error',
emptyTab: 'emptyTab',
// without tabs
emptyState: 'emptyState',
helpPagePath: {
type: String,
required: true,
},
emptyStateSvgPath: {
type: String,
required: true,
},
errorStateSvgPath: {
type: String,
required: true,
},
noPipelinesSvgPath: {
type: String,
required: true,
},
autoDevopsPath: {
type: String,
required: true,
},
hasGitlabCi: {
type: Boolean,
required: true,
},
canCreatePipeline: {
type: Boolean,
required: true,
},
ciLintPath: {
type: String,
required: false,
default: null,
},
scopes: {
all: 'all',
pending: 'pending',
running: 'running',
finished: 'finished',
branches: 'branches',
tags: 'tags',
resetCachePath: {
type: String,
required: false,
default: null,
},
computed: {
/**
* `hasGitlabCi` handles both internal and external CI.
* The order on which the checks are made in this method is
* important to guarantee we handle all the corner cases.
*/
stateToRender() {
const { stateMap } = this.$options;
newPipelinePath: {
type: String,
required: false,
default: null,
},
},
data() {
return {
// Start with loading state to avoid a glitch when the empty state will be rendered
isLoading: true,
state: this.store.state,
scope: getParameterByName('scope') || 'all',
page: getParameterByName('page') || '1',
requestData: {},
isResetCacheButtonLoading: false,
};
},
stateMap: {
// with tabs
loading: 'loading',
tableList: 'tableList',
error: 'error',
emptyTab: 'emptyTab',
// without tabs
emptyState: 'emptyState',
},
scopes: {
all: 'all',
pending: 'pending',
running: 'running',
finished: 'finished',
branches: 'branches',
tags: 'tags',
},
computed: {
/**
* `hasGitlabCi` handles both internal and external CI.
* The order on which the checks are made in this method is
* important to guarantee we handle all the corner cases.
*/
stateToRender() {
const { stateMap } = this.$options;
 
if (this.isLoading) {
return stateMap.loading;
}
if (this.isLoading) {
return stateMap.loading;
}
 
if (this.hasError) {
return stateMap.error;
}
if (this.hasError) {
return stateMap.error;
}
 
if (this.state.pipelines.length) {
return stateMap.tableList;
}
if (this.state.pipelines.length) {
return stateMap.tableList;
}
 
if ((this.scope !== 'all' && this.scope !== null) || this.hasGitlabCi) {
return stateMap.emptyTab;
}
if ((this.scope !== 'all' && this.scope !== null) || this.hasGitlabCi) {
return stateMap.emptyTab;
}
 
return stateMap.emptyState;
},
/**
* Tabs are rendered in all states except empty state.
* They are not rendered before the first request to avoid a flicker on first load.
*/
shouldRenderTabs() {
const { stateMap } = this.$options;
return (
this.hasMadeRequest &&
[stateMap.loading, stateMap.tableList, stateMap.error, stateMap.emptyTab].includes(
this.stateToRender,
)
);
},
return stateMap.emptyState;
},
/**
* Tabs are rendered in all states except empty state.
* They are not rendered before the first request to avoid a flicker on first load.
*/
shouldRenderTabs() {
const { stateMap } = this.$options;
return (
this.hasMadeRequest &&
[stateMap.loading, stateMap.tableList, stateMap.error, stateMap.emptyTab].includes(
this.stateToRender,
)
);
},
 
shouldRenderButtons() {
return (
(this.newPipelinePath || this.resetCachePath || this.ciLintPath) && this.shouldRenderTabs
);
},
shouldRenderButtons() {
return (
(this.newPipelinePath || this.resetCachePath || this.ciLintPath) && this.shouldRenderTabs
);
},
 
shouldRenderPagination() {
return (
!this.isLoading &&
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage
);
},
shouldRenderPagination() {
return (
!this.isLoading &&
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage
);
},
 
emptyTabMessage() {
const { scopes } = this.$options;
const possibleScopes = [scopes.pending, scopes.running, scopes.finished];
emptyTabMessage() {
const { scopes } = this.$options;
const possibleScopes = [scopes.pending, scopes.running, scopes.finished];
 
if (possibleScopes.includes(this.scope)) {
return sprintf(s__('Pipelines|There are currently no %{scope} pipelines.'), {
scope: this.scope,
});
}
if (possibleScopes.includes(this.scope)) {
return sprintf(s__('Pipelines|There are currently no %{scope} pipelines.'), {
scope: this.scope,
});
}
 
return s__('Pipelines|There are currently no pipelines.');
},
return s__('Pipelines|There are currently no pipelines.');
},
 
tabs() {
const { count } = this.state;
const { scopes } = this.$options;
tabs() {
const { count } = this.state;
const { scopes } = this.$options;
 
return [
{
name: __('All'),
scope: scopes.all,
count: count.all,
isActive: this.scope === 'all',
},
{
name: __('Pending'),
scope: scopes.pending,
count: count.pending,
isActive: this.scope === 'pending',
},
{
name: __('Running'),
scope: scopes.running,
count: count.running,
isActive: this.scope === 'running',
},
{
name: __('Finished'),
scope: scopes.finished,
count: count.finished,
isActive: this.scope === 'finished',
},
{
name: __('Branches'),
scope: scopes.branches,
isActive: this.scope === 'branches',
},
{
name: __('Tags'),
scope: scopes.tags,
isActive: this.scope === 'tags',
},
];
},
return [
{
name: __('All'),
scope: scopes.all,
count: count.all,
isActive: this.scope === 'all',
},
{
name: __('Pending'),
scope: scopes.pending,
count: count.pending,
isActive: this.scope === 'pending',
},
{
name: __('Running'),
scope: scopes.running,
count: count.running,
isActive: this.scope === 'running',
},
{
name: __('Finished'),
scope: scopes.finished,
count: count.finished,
isActive: this.scope === 'finished',
},
{
name: __('Branches'),
scope: scopes.branches,
isActive: this.scope === 'branches',
},
{
name: __('Tags'),
scope: scopes.tags,
isActive: this.scope === 'tags',
},
];
},
created() {
this.service = new PipelinesService(this.endpoint);
this.requestData = { page: this.page, scope: this.scope };
},
created() {
this.service = new PipelinesService(this.endpoint);
this.requestData = { page: this.page, scope: this.scope };
},
methods: {
successCallback(resp) {
// Because we are polling & the user is interacting verify if the response received
// matches the last request made
if (_.isEqual(resp.config.params, this.requestData)) {
this.store.storeCount(resp.data.count);
this.store.storePagination(resp.headers);
this.setCommonData(resp.data.pipelines);
}
},
methods: {
successCallback(resp) {
// Because we are polling & the user is interacting verify if the response received
// matches the last request made
if (_.isEqual(resp.config.params, this.requestData)) {
this.store.storeCount(resp.data.count);
this.store.storePagination(resp.headers);
this.setCommonData(resp.data.pipelines);
}
},
/**
* Handles URL and query parameter changes.
* When the user uses the pagination or the tabs,
* - update URL
* - Make API request to the server with new parameters
* - Update the polling function
* - Update the internal state
*/
updateContent(parameters) {
this.updateInternalState(parameters);
/**
* Handles URL and query parameter changes.
* When the user uses the pagination or the tabs,
* - update URL
* - Make API request to the server with new parameters
* - Update the polling function
* - Update the internal state
*/
updateContent(parameters) {
this.updateInternalState(parameters);
 
// fetch new data
return this.service
.getPipelines(this.requestData)
.then(response => {
this.isLoading = false;
this.successCallback(response);
// fetch new data
return this.service
.getPipelines(this.requestData)
.then(response => {
this.isLoading = false;
this.successCallback(response);
 
// restart polling
this.poll.restart({ data: this.requestData });
})
.catch(() => {
this.isLoading = false;
this.errorCallback();
// restart polling
this.poll.restart({ data: this.requestData });
})
.catch(() => {
this.isLoading = false;
this.errorCallback();
 
// restart polling
this.poll.restart({ data: this.requestData });
});
},
// restart polling
this.poll.restart({ data: this.requestData });
});
},
 
handleResetRunnersCache(endpoint) {
this.isResetCacheButtonLoading = true;
handleResetRunnersCache(endpoint) {
this.isResetCacheButtonLoading = true;
 
this.service
.postAction(endpoint)
.then(() => {
this.isResetCacheButtonLoading = false;
createFlash(s__('Pipelines|Project cache successfully reset.'), 'notice');
})
.catch(() => {
this.isResetCacheButtonLoading = false;
createFlash(s__('Pipelines|Something went wrong while cleaning runners cache.'));
});
},
this.service
.postAction(endpoint)
.then(() => {
this.isResetCacheButtonLoading = false;
createFlash(s__('Pipelines|Project cache successfully reset.'), 'notice');
})
.catch(() => {
this.isResetCacheButtonLoading = false;
createFlash(s__('Pipelines|Something went wrong while cleaning runners cache.'));
});
},
};
},
};
</script>
<template>
<div class="pipelines-container">
Loading
Loading
<script>
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import icon from '../../vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip';
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import icon from '../../vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip';
 
export default {
directives: {
tooltip,
export default {
directives: {
tooltip,
},
components: {
loadingIcon,
icon,
},
props: {
actions: {
type: Array,
required: true,
},
components: {
loadingIcon,
icon,
},
props: {
actions: {
type: Array,
required: true,
},
},
data() {
return {
isLoading: false,
};
},
methods: {
onClickAction(endpoint) {
this.isLoading = true;
},
data() {
return {
isLoading: false,
};
},
methods: {
onClickAction(endpoint) {
this.isLoading = true;
 
eventHub.$emit('postAction', endpoint);
},
eventHub.$emit('postAction', endpoint);
},
 
isActionDisabled(action) {
if (action.playable === undefined) {
return false;
}
isActionDisabled(action) {
if (action.playable === undefined) {
return false;
}
 
return !action.playable;
},
return !action.playable;
},
};
},
};
</script>
<template>
<div class="btn-group">
Loading
Loading
<script>
import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue';
 
export default {
directives: {
tooltip,
export default {
directives: {
tooltip,
},
components: {
icon,
},
props: {
artifacts: {
type: Array,
required: true,
},
components: {
icon,
},
props: {
artifacts: {
type: Array,
required: true,
},
},
};
},
};
</script>
<template>
<div
Loading
Loading
<script>
import Modal from '~/vue_shared/components/gl_modal.vue';
import { s__, sprintf } from '~/locale';
import PipelinesTableRowComponent from './pipelines_table_row.vue';
import eventHub from '../event_hub';
import Modal from '~/vue_shared/components/gl_modal.vue';
import { s__, sprintf } from '~/locale';
import PipelinesTableRowComponent from './pipelines_table_row.vue';
import eventHub from '../event_hub';
 
/**
* Pipelines Table Component.
*
* Given an array of objects, renders a table.
*/
export default {
components: {
PipelinesTableRowComponent,
Modal,
/**
* Pipelines Table Component.
*
* Given an array of objects, renders a table.
*/
export default {
components: {
PipelinesTableRowComponent,
Modal,
},
props: {
pipelines: {
type: Array,
required: true,
},
props: {
pipelines: {
type: Array,
required: true,
},
updateGraphDropdown: {
type: Boolean,
required: false,
default: false,
},
autoDevopsHelpPath: {
type: String,
required: true,
},
viewType: {
type: String,
required: true,
},
updateGraphDropdown: {
type: Boolean,
required: false,
default: false,
},
data() {
return {
pipelineId: '',
endpoint: '',
cancelingPipeline: null,
};
autoDevopsHelpPath: {
type: String,
required: true,
},
computed: {
modalTitle() {
return sprintf(s__('Pipeline|Stop pipeline #%{pipelineId}?'), {
viewType: {
type: String,
required: true,
},
},
data() {
return {
pipelineId: '',
endpoint: '',
cancelingPipeline: null,
};
},
computed: {
modalTitle() {
return sprintf(
s__('Pipeline|Stop pipeline #%{pipelineId}?'),
{
pipelineId: `${this.pipelineId}`,
}, false);
},
modalText() {
return sprintf(s__('Pipeline|You’re about to stop pipeline %{pipelineId}.'), {
pipelineId: `<strong>#${this.pipelineId}</strong>`,
}, false);
},
},
false,
);
},
created() {
eventHub.$on('openConfirmationModal', this.setModalData);
modalText() {
return sprintf(
s__('Pipeline|You’re about to stop pipeline %{pipelineId}.'),
{
pipelineId: `<strong>#${this.pipelineId}</strong>`,
},
false,
);
},
beforeDestroy() {
eventHub.$off('openConfirmationModal', this.setModalData);
},
created() {
eventHub.$on('openConfirmationModal', this.setModalData);
},
beforeDestroy() {
eventHub.$off('openConfirmationModal', this.setModalData);
},
methods: {
setModalData(data) {
this.pipelineId = data.pipelineId;
this.endpoint = data.endpoint;
},
methods: {
setModalData(data) {
this.pipelineId = data.pipelineId;
this.endpoint = data.endpoint;
},
onSubmit() {
eventHub.$emit('postAction', this.endpoint);
this.cancelingPipeline = this.pipelineId;
},
onSubmit() {
eventHub.$emit('postAction', this.endpoint);
this.cancelingPipeline = this.pipelineId;
},
};
},
};
</script>
<template>
<div class="ci-table">
Loading
Loading
<script>
import eventHub from '../event_hub';
import PipelinesActionsComponent from './pipelines_actions.vue';
import PipelinesArtifactsComponent from './pipelines_artifacts.vue';
import CiBadge from '../../vue_shared/components/ci_badge_link.vue';
import PipelineStage from './stage.vue';
import PipelineUrl from './pipeline_url.vue';
import PipelinesTimeago from './time_ago.vue';
import CommitComponent from '../../vue_shared/components/commit.vue';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
import Icon from '../../vue_shared/components/icon.vue';
import { PIPELINES_TABLE } from '../constants';
import eventHub from '../event_hub';
import PipelinesActionsComponent from './pipelines_actions.vue';
import PipelinesArtifactsComponent from './pipelines_artifacts.vue';
import CiBadge from '../../vue_shared/components/ci_badge_link.vue';
import PipelineStage from './stage.vue';
import PipelineUrl from './pipeline_url.vue';
import PipelinesTimeago from './time_ago.vue';
import CommitComponent from '../../vue_shared/components/commit.vue';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
import Icon from '../../vue_shared/components/icon.vue';
import { PIPELINES_TABLE } from '../constants';
 
/**
* Pipeline table row.
*
* Given the received object renders a table row in the pipelines' table.
*/
export default {
components: {
PipelinesActionsComponent,
PipelinesArtifactsComponent,
CommitComponent,
PipelineStage,
PipelineUrl,
CiBadge,
PipelinesTimeago,
LoadingButton,
Icon,
/**
* Pipeline table row.
*
* Given the received object renders a table row in the pipelines' table.
*/
export default {
components: {
PipelinesActionsComponent,
PipelinesArtifactsComponent,
CommitComponent,
PipelineStage,
PipelineUrl,
CiBadge,
PipelinesTimeago,
LoadingButton,
Icon,
},
props: {
pipeline: {
type: Object,
required: true,
},
props: {
pipeline: {
type: Object,
required: true,
},
updateGraphDropdown: {
type: Boolean,
required: false,
default: false,
},
autoDevopsHelpPath: {
type: String,
required: true,
},
viewType: {
type: String,
required: true,
},
cancelingPipeline: {
type: String,
required: false,
default: null,
},
updateGraphDropdown: {
type: Boolean,
required: false,
default: false,
},
pipelinesTable: PIPELINES_TABLE,
data() {
return {
isRetrying: false,
};
autoDevopsHelpPath: {
type: String,
required: true,
},
computed: {
/**
* If provided, returns the commit tag.
* Needed to render the commit component column.
*
* This field needs a lot of verification, because of different possible cases:
*
* 1. person who is an author of a commit might be a GitLab user
* 2. if person who is an author of a commit is a GitLab user he/she can have a GitLab avatar
* 3. If GitLab user does not have avatar he/she might have a Gravatar
* 4. If committer is not a GitLab User he/she can have a Gravatar
* 5. We do not have consistent API object in this case
* 6. We should improve API and the code
*
* @returns {Object|Undefined}
*/
commitAuthor() {
let commitAuthorInformation;
viewType: {
type: String,
required: true,
},
cancelingPipeline: {
type: String,
required: false,
default: null,
},
},
pipelinesTable: PIPELINES_TABLE,
data() {
return {
isRetrying: false,
};
},
computed: {
/**
* If provided, returns the commit tag.
* Needed to render the commit component column.
*
* This field needs a lot of verification, because of different possible cases:
*
* 1. person who is an author of a commit might be a GitLab user
* 2. if person who is an author of a commit is a GitLab user he/she can have a GitLab avatar
* 3. If GitLab user does not have avatar he/she might have a Gravatar
* 4. If committer is not a GitLab User he/she can have a Gravatar
* 5. We do not have consistent API object in this case
* 6. We should improve API and the code
*
* @returns {Object|Undefined}
*/
commitAuthor() {
let commitAuthorInformation;
 
if (!this.pipeline || !this.pipeline.commit) {
return null;
}
if (!this.pipeline || !this.pipeline.commit) {
return null;
}
 
// 1. person who is an author of a commit might be a GitLab user
if (this.pipeline.commit.author) {
// 2. if person who is an author of a commit is a GitLab user
// he/she can have a GitLab avatar
if (this.pipeline.commit.author.avatar_url) {
commitAuthorInformation = this.pipeline.commit.author;
// 1. person who is an author of a commit might be a GitLab user
if (this.pipeline.commit.author) {
// 2. if person who is an author of a commit is a GitLab user
// he/she can have a GitLab avatar
if (this.pipeline.commit.author.avatar_url) {
commitAuthorInformation = this.pipeline.commit.author;
 
// 3. If GitLab user does not have avatar he/she might have a Gravatar
} else if (this.pipeline.commit.author_gravatar_url) {
commitAuthorInformation = Object.assign({}, this.pipeline.commit.author, {
avatar_url: this.pipeline.commit.author_gravatar_url,
});
}
// 4. If committer is not a GitLab User he/she can have a Gravatar
} else {
commitAuthorInformation = {
// 3. If GitLab user does not have avatar he/she might have a Gravatar
} else if (this.pipeline.commit.author_gravatar_url) {
commitAuthorInformation = Object.assign({}, this.pipeline.commit.author, {
avatar_url: this.pipeline.commit.author_gravatar_url,
path: `mailto:${this.pipeline.commit.author_email}`,
username: this.pipeline.commit.author_name,
};
});
}
// 4. If committer is not a GitLab User he/she can have a Gravatar
} else {
commitAuthorInformation = {
avatar_url: this.pipeline.commit.author_gravatar_url,
path: `mailto:${this.pipeline.commit.author_email}`,
username: this.pipeline.commit.author_name,
};
}
 
return commitAuthorInformation;
},
return commitAuthorInformation;
},
 
/**
* If provided, returns the commit tag.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitTag() {
if (this.pipeline.ref &&
this.pipeline.ref.tag) {
return this.pipeline.ref.tag;
}
return undefined;
},
/**
* If provided, returns the commit tag.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitTag() {
if (this.pipeline.ref && this.pipeline.ref.tag) {
return this.pipeline.ref.tag;
}
return undefined;
},
 
/**
* If provided, returns the commit ref.
* Needed to render the commit component column.
*
* Matches `path` prop sent in the API to `ref_url` prop needed
* in the commit component.
*
* @returns {Object|Undefined}
*/
commitRef() {
if (this.pipeline.ref) {
return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => {
if (prop === 'path') {
// eslint-disable-next-line no-param-reassign
accumulator.ref_url = this.pipeline.ref[prop];
} else {
// eslint-disable-next-line no-param-reassign
accumulator[prop] = this.pipeline.ref[prop];
}
return accumulator;
}, {});
}
/**
* If provided, returns the commit ref.
* Needed to render the commit component column.
*
* Matches `path` prop sent in the API to `ref_url` prop needed
* in the commit component.
*
* @returns {Object|Undefined}
*/
commitRef() {
if (this.pipeline.ref) {
return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => {
if (prop === 'path') {
// eslint-disable-next-line no-param-reassign
accumulator.ref_url = this.pipeline.ref[prop];
} else {
// eslint-disable-next-line no-param-reassign
accumulator[prop] = this.pipeline.ref[prop];
}
return accumulator;
}, {});
}
 
return undefined;
},
return undefined;
},
 
/**
* If provided, returns the commit url.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitUrl() {
if (this.pipeline.commit &&
this.pipeline.commit.commit_path) {
return this.pipeline.commit.commit_path;
}
return undefined;
},
/**
* If provided, returns the commit url.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitUrl() {
if (this.pipeline.commit && this.pipeline.commit.commit_path) {
return this.pipeline.commit.commit_path;
}
return undefined;
},
 
/**
* If provided, returns the commit short sha.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitShortSha() {
if (this.pipeline.commit &&
this.pipeline.commit.short_id) {
return this.pipeline.commit.short_id;
}
return undefined;
},
/**
* If provided, returns the commit short sha.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitShortSha() {
if (this.pipeline.commit && this.pipeline.commit.short_id) {
return this.pipeline.commit.short_id;
}
return undefined;
},
 
/**
* If provided, returns the commit title.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitTitle() {
if (this.pipeline.commit &&
this.pipeline.commit.title) {
return this.pipeline.commit.title;
}
return undefined;
},
/**
* If provided, returns the commit title.
* Needed to render the commit component column.
*
* @returns {String|Undefined}
*/
commitTitle() {
if (this.pipeline.commit && this.pipeline.commit.title) {
return this.pipeline.commit.title;
}
return undefined;
},
 
/**
* Timeago components expects a number
*
* @return {type} description
*/
pipelineDuration() {
if (this.pipeline.details && this.pipeline.details.duration) {
return this.pipeline.details.duration;
}
/**
* Timeago components expects a number
*
* @return {type} description
*/
pipelineDuration() {
if (this.pipeline.details && this.pipeline.details.duration) {
return this.pipeline.details.duration;
}
 
return 0;
},
return 0;
},
 
/**
* Timeago component expects a String.
*
* @return {String}
*/
pipelineFinishedAt() {
if (this.pipeline.details && this.pipeline.details.finished_at) {
return this.pipeline.details.finished_at;
}
/**
* Timeago component expects a String.
*
* @return {String}
*/
pipelineFinishedAt() {
if (this.pipeline.details && this.pipeline.details.finished_at) {
return this.pipeline.details.finished_at;
}
 
return '';
},
return '';
},
 
pipelineStatus() {
if (this.pipeline.details && this.pipeline.details.status) {
return this.pipeline.details.status;
}
return {};
},
pipelineStatus() {
if (this.pipeline.details && this.pipeline.details.status) {
return this.pipeline.details.status;
}
return {};
},
 
displayPipelineActions() {
return this.pipeline.flags.retryable ||
this.pipeline.flags.cancelable ||
this.pipeline.details.manual_actions.length ||
this.pipeline.details.artifacts.length;
},
displayPipelineActions() {
return (
this.pipeline.flags.retryable ||
this.pipeline.flags.cancelable ||
this.pipeline.details.manual_actions.length ||
this.pipeline.details.artifacts.length
);
},
 
isChildView() {
return this.viewType === 'child';
},
isChildView() {
return this.viewType === 'child';
},
 
isCancelling() {
return this.cancelingPipeline === this.pipeline.id;
},
isCancelling() {
return this.cancelingPipeline === this.pipeline.id;
},
},
 
methods: {
handleCancelClick() {
eventHub.$emit('openConfirmationModal', {
pipelineId: this.pipeline.id,
endpoint: this.pipeline.cancel_path,
});
},
handleRetryClick() {
this.isRetrying = true;
eventHub.$emit('retryPipeline', this.pipeline.retry_path);
},
methods: {
handleCancelClick() {
eventHub.$emit('openConfirmationModal', {
pipelineId: this.pipeline.id,
endpoint: this.pipeline.cancel_path,
});
},
handleRetryClick() {
this.isRetrying = true;
eventHub.$emit('retryPipeline', this.pipeline.retry_path);
},
};
},
};
</script>
<template>
<div class="commit gl-responsive-table-row">
Loading
Loading
<script>
import iconTimerSvg from 'icons/_icon_timer.svg';
import '../../lib/utils/datetime_utility';
import tooltip from '../../vue_shared/directives/tooltip';
import timeagoMixin from '../../vue_shared/mixins/timeago';
import iconTimerSvg from 'icons/_icon_timer.svg';
import '../../lib/utils/datetime_utility';
import tooltip from '../../vue_shared/directives/tooltip';
import timeagoMixin from '../../vue_shared/mixins/timeago';
 
export default {
directives: {
tooltip,
export default {
directives: {
tooltip,
},
mixins: [timeagoMixin],
props: {
finishedTime: {
type: String,
required: true,
},
mixins: [
timeagoMixin,
],
props: {
finishedTime: {
type: String,
required: true,
},
duration: {
type: Number,
required: true,
},
duration: {
type: Number,
required: true,
},
data() {
return {
iconTimerSvg,
};
},
data() {
return {
iconTimerSvg,
};
},
computed: {
hasDuration() {
return this.duration > 0;
},
computed: {
hasDuration() {
return this.duration > 0;
},
hasFinishedTime() {
return this.finishedTime !== '';
},
durationFormated() {
const date = new Date(this.duration * 1000);
hasFinishedTime() {
return this.finishedTime !== '';
},
durationFormated() {
const date = new Date(this.duration * 1000);
 
let hh = date.getUTCHours();
let mm = date.getUTCMinutes();
let ss = date.getSeconds();
let hh = date.getUTCHours();
let mm = date.getUTCMinutes();
let ss = date.getSeconds();
 
// left pad
if (hh < 10) {
hh = `0${hh}`;
}
if (mm < 10) {
mm = `0${mm}`;
}
if (ss < 10) {
ss = `0${ss}`;
}
// left pad
if (hh < 10) {
hh = `0${hh}`;
}
if (mm < 10) {
mm = `0${mm}`;
}
if (ss < 10) {
ss = `0${ss}`;
}
 
return `${hh}:${mm}:${ss}`;
},
return `${hh}:${mm}:${ss}`;
},
};
},
};
</script>
<template>
<div class="table-section section-15 pipelines-time-ago">
Loading
Loading
Loading
Loading
@@ -75,8 +75,7 @@ export default {
// Stop polling
this.poll.stop();
// Update the table
return this.getPipelines()
.then(() => this.poll.restart());
return this.getPipelines().then(() => this.poll.restart());
},
fetchPipelines() {
if (!this.isMakingRequest) {
Loading
Loading
@@ -86,9 +85,10 @@ export default {
}
},
getPipelines() {
return this.service.getPipelines(this.requestData)
return this.service
.getPipelines(this.requestData)
.then(response => this.successCallback(response))
.catch((error) => this.errorCallback(error));
.catch(error => this.errorCallback(error));
},
setCommonData(pipelines) {
this.store.storePipelines(pipelines);
Loading
Loading
@@ -118,7 +118,8 @@ export default {
}
},
postAction(endpoint) {
this.service.postAction(endpoint)
this.service
.postAction(endpoint)
.then(() => this.fetchPipelines())
.catch(() => Flash(__('An error occurred while making the request.')));
},
Loading
Loading
Loading
Loading
@@ -31,7 +31,8 @@ export default () => {
requestRefreshPipelineGraph() {
// When an action is clicked
// (wether in the dropdown or in the main nodes, we refresh the big graph)
this.mediator.refreshPipeline()
this.mediator
.refreshPipeline()
.catch(() => Flash(__('An error occurred while making the request.')));
},
},
Loading
Loading
Loading
Loading
@@ -52,7 +52,8 @@ export default class pipelinesMediator {
refreshPipeline() {
this.poll.stop();
 
return this.service.getPipeline()
return this.service
.getPipeline()
.then(response => this.successCallback(response))
.catch(() => this.errorCallback())
.finally(() => this.poll.restart());
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment