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