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
9867eaf3
Commit
9867eaf3
authored
Oct 10, 2018
by
Mike Greiling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prettify issue_show and jobs modules
parent
550f5574
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1074 additions
and
1080 deletions
+1074
-1080
app/assets/javascripts/issue_show/components/app.vue
app/assets/javascripts/issue_show/components/app.vue
+257
-259
app/assets/javascripts/issue_show/components/description.vue
app/assets/javascripts/issue_show/components/description.vue
+88
-93
app/assets/javascripts/issue_show/components/edit_actions.vue
...assets/javascripts/issue_show/components/edit_actions.vue
+53
-53
app/assets/javascripts/issue_show/components/edited.vue
app/assets/javascripts/issue_show/components/edited.vue
+25
-26
app/assets/javascripts/issue_show/components/fields/description.vue
.../javascripts/issue_show/components/fields/description.vue
+37
-37
app/assets/javascripts/issue_show/components/fields/description_template.vue
...pts/issue_show/components/fields/description_template.vue
+38
-38
app/assets/javascripts/issue_show/components/fields/title.vue
...assets/javascripts/issue_show/components/fields/title.vue
+9
-9
app/assets/javascripts/issue_show/components/form.vue
app/assets/javascripts/issue_show/components/form.vue
+71
-71
app/assets/javascripts/issue_show/components/locked_warning.vue
...sets/javascripts/issue_show/components/locked_warning.vue
+6
-6
app/assets/javascripts/issue_show/stores/index.js
app/assets/javascripts/issue_show/stores/index.js
+4
-2
app/assets/javascripts/jobs/components/artifacts_block.vue
app/assets/javascripts/jobs/components/artifacts_block.vue
+20
-22
app/assets/javascripts/jobs/components/commit_block.vue
app/assets/javascripts/jobs/components/commit_block.vue
+19
-19
app/assets/javascripts/jobs/components/empty_state.vue
app/assets/javascripts/jobs/components/empty_state.vue
+32
-32
app/assets/javascripts/jobs/components/environments_block.vue
...assets/javascripts/jobs/components/environments_block.vue
+106
-104
app/assets/javascripts/jobs/components/erased_block.vue
app/assets/javascripts/jobs/components/erased_block.vue
+20
-20
app/assets/javascripts/jobs/components/job_log.vue
app/assets/javascripts/jobs/components/job_log.vue
+12
-12
app/assets/javascripts/jobs/components/job_log_controllers.vue
...ssets/javascripts/jobs/components/job_log_controllers.vue
+57
-58
app/assets/javascripts/jobs/components/jobs_container.vue
app/assets/javascripts/jobs/components/jobs_container.vue
+27
-27
app/assets/javascripts/jobs/components/sidebar.vue
app/assets/javascripts/jobs/components/sidebar.vue
+101
-101
app/assets/javascripts/jobs/components/sidebar_detail_row.vue
...assets/javascripts/jobs/components/sidebar_detail_row.vue
+25
-25
app/assets/javascripts/jobs/components/stages_dropdown.vue
app/assets/javascripts/jobs/components/stages_dropdown.vue
+40
-40
app/assets/javascripts/jobs/components/trigger_block.vue
app/assets/javascripts/jobs/components/trigger_block.vue
+20
-20
app/assets/javascripts/jobs/store/index.js
app/assets/javascripts/jobs/store/index.js
+7
-6
No files found.
app/assets/javascripts/issue_show/components/app.vue
View file @
9867eaf3
This diff is collapsed.
Click to expand it.
app/assets/javascripts/issue_show/components/description.vue
View file @
9867eaf3
<
script
>
<
script
>
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
animateMixin
from
'
../mixins/animate
'
;
import
animateMixin
from
'
../mixins/animate
'
;
import
TaskList
from
'
../../task_list
'
;
import
TaskList
from
'
../../task_list
'
;
import
recaptchaModalImplementor
from
'
../../vue_shared/mixins/recaptcha_modal_implementor
'
;
import
recaptchaModalImplementor
from
'
../../vue_shared/mixins/recaptcha_modal_implementor
'
;
export
default
{
export
default
{
mixins
:
[
mixins
:
[
animateMixin
,
recaptchaModalImplementor
],
animateMixin
,
recaptchaModalImplementor
,
],
props
:
{
props
:
{
canUpdate
:
{
canUpdate
:
{
type
:
Boolean
,
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
descriptionHtml
:
{
type
:
String
,
required
:
true
,
},
descriptionText
:
{
type
:
String
,
required
:
true
,
},
taskStatus
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
issuableType
:
{
type
:
String
,
required
:
false
,
default
:
'
issue
'
,
},
updateUrl
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
},
},
data
()
{
descriptionHtml
:
{
return
{
type
:
String
,
preAnimation
:
false
,
required
:
true
,
pulseAnimation
:
false
,
};
},
},
watch
:
{
descriptionText
:
{
descriptionHtml
()
{
type
:
String
,
this
.
animateChange
();
required
:
true
,
},
taskStatus
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
issuableType
:
{
type
:
String
,
required
:
false
,
default
:
'
issue
'
,
},
updateUrl
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
},
data
()
{
return
{
preAnimation
:
false
,
pulseAnimation
:
false
,
};
},
watch
:
{
descriptionHtml
()
{
this
.
animateChange
();
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
this
.
renderGFM
();
this
.
renderGFM
();
});
});
},
taskStatus
()
{
this
.
updateTaskStatusText
();
},
},
},
mounted
()
{
taskStatus
()
{
this
.
renderGFM
();
this
.
updateTaskStatusText
();
this
.
updateTaskStatusText
();
},
},
methods
:
{
},
renderGFM
()
{
mounted
()
{
$
(
this
.
$refs
[
'
gfm-content
'
]).
renderGFM
();
this
.
renderGFM
();
this
.
updateTaskStatusText
();
},
methods
:
{
renderGFM
()
{
$
(
this
.
$refs
[
'
gfm-content
'
]).
renderGFM
();
if
(
this
.
canUpdate
)
{
if
(
this
.
canUpdate
)
{
// eslint-disable-next-line no-new
// eslint-disable-next-line no-new
new
TaskList
({
new
TaskList
({
dataType
:
this
.
issuableType
,
dataType
:
this
.
issuableType
,
fieldName
:
'
description
'
,
fieldName
:
'
description
'
,
selector
:
'
.detail-page-description
'
,
selector
:
'
.detail-page-description
'
,
onSuccess
:
this
.
taskListUpdateSuccess
.
bind
(
this
),
onSuccess
:
this
.
taskListUpdateSuccess
.
bind
(
this
),
});
});
}
}
},
},
taskListUpdateSuccess
(
data
)
{
taskListUpdateSuccess
(
data
)
{
try
{
try
{
this
.
checkForSpam
(
data
);
this
.
checkForSpam
(
data
);
this
.
closeRecaptcha
();
this
.
closeRecaptcha
();
}
catch
(
error
)
{
}
catch
(
error
)
{
if
(
error
&&
error
.
name
===
'
SpamError
'
)
this
.
openRecaptcha
();
if
(
error
&&
error
.
name
===
'
SpamError
'
)
this
.
openRecaptcha
();
}
}
},
},
updateTaskStatusText
()
{
updateTaskStatusText
()
{
const
taskRegexMatches
=
this
.
taskStatus
.
match
(
/
(\d
+
)
of
((?!
0
)\d
+
)
/
);
const
taskRegexMatches
=
this
.
taskStatus
.
match
(
/
(\d
+
)
of
((?!
0
)\d
+
)
/
);
const
$issuableHeader
=
$
(
'
.issuable-meta
'
);
const
$issuableHeader
=
$
(
'
.issuable-meta
'
);
const
$tasks
=
$
(
'
#task_status
'
,
$issuableHeader
);
const
$tasks
=
$
(
'
#task_status
'
,
$issuableHeader
);
const
$tasksShort
=
$
(
'
#task_status_short
'
,
$issuableHeader
);
const
$tasksShort
=
$
(
'
#task_status_short
'
,
$issuableHeader
);
if
(
taskRegexMatches
)
{
if
(
taskRegexMatches
)
{
$tasks
.
text
(
this
.
taskStatus
);
$tasks
.
text
(
this
.
taskStatus
);
$tasksShort
.
text
(
$tasksShort
.
text
(
`
${
taskRegexMatches
[
1
]}
/
${
taskRegexMatches
[
2
]}
task
${
taskRegexMatches
[
2
]
>
1
?
`
${
taskRegexMatches
[
1
]}
/
${
taskRegexMatches
[
2
]}
task
${
taskRegexMatches
[
2
]
>
1
?
'
s
'
:
''
}
`
,
'
s
'
:
);
''
}
`
,
}
else
{
);
$tasks
.
text
(
''
);
}
else
{
$tasksShort
.
text
(
''
);
$tasks
.
text
(
''
);
}
$tasksShort
.
text
(
''
);
}
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/edit_actions.vue
View file @
9867eaf3
<
script
>
<
script
>
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
updateMixin
from
'
../mixins/update
'
;
import
updateMixin
from
'
../mixins/update
'
;
import
eventHub
from
'
../event_hub
'
;
import
eventHub
from
'
../event_hub
'
;
const
issuableTypes
=
{
const
issuableTypes
=
{
issue
:
__
(
'
Issue
'
),
issue
:
__
(
'
Issue
'
),
epic
:
__
(
'
Epic
'
),
epic
:
__
(
'
Epic
'
),
};
};
export
default
{
export
default
{
mixins
:
[
updateMixin
],
mixins
:
[
updateMixin
],
props
:
{
props
:
{
canDestroy
:
{
canDestroy
:
{
type
:
Boolean
,
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
formState
:
{
type
:
Object
,
required
:
true
,
},
showDeleteButton
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
issuableType
:
{
type
:
String
,
required
:
true
,
},
},
},
data
()
{
formState
:
{
return
{
type
:
Object
,
deleteLoading
:
false
,
required
:
true
,
};
},
},
computed
:
{
showDeleteButton
:
{
isSubmitEnabled
()
{
type
:
Boolean
,
return
this
.
formState
.
title
.
trim
()
!==
''
;
required
:
false
,
},
default
:
true
,
shouldShowDeleteButton
()
{
return
this
.
canDestroy
&&
this
.
showDeleteButton
;
},
},
},
methods
:
{
issuableType
:
{
closeForm
()
{
type
:
String
,
eventHub
.
$emit
(
'
close.form
'
);
required
:
true
,
},
},
deleteIssuable
()
{
},
const
confirmMessage
=
sprintf
(
__
(
'
%{issuableType} will be removed! Are you sure?
'
),
{
data
()
{
issuableType
:
issuableTypes
[
this
.
issuableType
],
return
{
});
deleteLoading
:
false
,
// eslint-disable-next-line no-alert
};
if
(
window
.
confirm
(
confirmMessage
))
{
},
this
.
deleteLoading
=
true
;
computed
:
{
isSubmitEnabled
()
{
return
this
.
formState
.
title
.
trim
()
!==
''
;
},
shouldShowDeleteButton
()
{
return
this
.
canDestroy
&&
this
.
showDeleteButton
;
},
},
methods
:
{
closeForm
()
{
eventHub
.
$emit
(
'
close.form
'
);
},
deleteIssuable
()
{
const
confirmMessage
=
sprintf
(
__
(
'
%{issuableType} will be removed! Are you sure?
'
),
{
issuableType
:
issuableTypes
[
this
.
issuableType
],
});
// eslint-disable-next-line no-alert
if
(
window
.
confirm
(
confirmMessage
))
{
this
.
deleteLoading
=
true
;
eventHub
.
$emit
(
'
delete.issuable
'
);
eventHub
.
$emit
(
'
delete.issuable
'
);
}
}
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/edited.vue
View file @
9867eaf3
<
script
>
<
script
>
import
timeAgoTooltip
from
'
../../vue_shared/components/time_ago_tooltip.vue
'
;
import
timeAgoTooltip
from
'
../../vue_shared/components/time_ago_tooltip.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
timeAgoTooltip
,
timeAgoTooltip
,
},
props
:
{
updatedAt
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
props
:
{
updatedByName
:
{
updatedAt
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
default
:
''
,
default
:
''
,
},
updatedByName
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
updatedByPath
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
},
computed
:
{
updatedByPath
:
{
hasUpdatedBy
()
{
type
:
String
,
return
this
.
updatedByName
&&
this
.
updatedByPath
;
required
:
false
,
}
,
default
:
''
,
},
},
};
},
computed
:
{
hasUpdatedBy
()
{
return
this
.
updatedByName
&&
this
.
updatedByPath
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -53,4 +53,3 @@
...
@@ -53,4 +53,3 @@
</span>
</span>
</small>
</small>
</
template
>
</
template
>
app/assets/javascripts/issue_show/components/fields/description.vue
View file @
9867eaf3
<
script
>
<
script
>
import
updateMixin
from
'
../../mixins/update
'
;
import
updateMixin
from
'
../../mixins/update
'
;
import
markdownField
from
'
../../../vue_shared/components/markdown/field.vue
'
;
import
markdownField
from
'
../../../vue_shared/components/markdown/field.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
markdownField
,
markdownField
,
},
mixins
:
[
updateMixin
],
props
:
{
formState
:
{
type
:
Object
,
required
:
true
,
},
},
mixins
:
[
updateMixin
],
markdownPreviewPath
:
{
props
:
{
type
:
String
,
formState
:
{
required
:
true
,
type
:
Object
,
required
:
true
,
},
markdownPreviewPath
:
{
type
:
String
,
required
:
true
,
},
markdownDocsPath
:
{
type
:
String
,
required
:
true
,
},
markdownVersion
:
{
type
:
Number
,
required
:
false
,
default
:
0
,
},
canAttachFile
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
enableAutocomplete
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
},
mounted
()
{
markdownDocsPath
:
{
this
.
$refs
.
textarea
.
focus
();
type
:
String
,
required
:
true
,
},
},
};
markdownVersion
:
{
type
:
Number
,
required
:
false
,
default
:
0
,
},
canAttachFile
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
enableAutocomplete
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
mounted
()
{
this
.
$refs
.
textarea
.
focus
();
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/fields/description_template.vue
View file @
9867eaf3
<
script
>
<
script
>
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
IssuableTemplateSelectors
from
'
../../../templates/issuable_template_selectors
'
;
import
IssuableTemplateSelectors
from
'
../../../templates/issuable_template_selectors
'
;
export
default
{
export
default
{
props
:
{
props
:
{
formState
:
{
formState
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
issuableTemplates
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
},
},
computed
:
{
issuableTemplates
:
{
issuableTemplatesJson
()
{
type
:
Array
,
return
JSON
.
stringify
(
this
.
issuableTemplates
);
required
:
false
,
}
,
default
:
()
=>
[]
,
},
},
mounted
()
{
projectPath
:
{
// Create the editor for the template
type
:
String
,
const
editor
=
document
.
querySelector
(
'
.detail-page-description .note-textarea
'
)
||
{};
required
:
true
,
editor
.
setValue
=
(
val
)
=>
{
},
this
.
formState
.
description
=
val
;
projectNamespace
:
{
};
type
:
String
,
editor
.
getValue
=
()
=>
this
.
formState
.
description
;
required
:
true
,
this
.
issuableTemplate
=
new
IssuableTemplateSelectors
({
$dropdowns
:
$
(
this
.
$refs
.
toggle
),
editor
,
});
},
},
};
},
computed
:
{
issuableTemplatesJson
()
{
return
JSON
.
stringify
(
this
.
issuableTemplates
);
},
},
mounted
()
{
// Create the editor for the template
const
editor
=
document
.
querySelector
(
'
.detail-page-description .note-textarea
'
)
||
{};
editor
.
setValue
=
val
=>
{
this
.
formState
.
description
=
val
;
};
editor
.
getValue
=
()
=>
this
.
formState
.
description
;
this
.
issuableTemplate
=
new
IssuableTemplateSelectors
({
$dropdowns
:
$
(
this
.
$refs
.
toggle
),
editor
,
});
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/fields/title.vue
View file @
9867eaf3
<
script
>
<
script
>
import
updateMixin
from
'
../../mixins/update
'
;
import
updateMixin
from
'
../../mixins/update
'
;
export
default
{
export
default
{
mixins
:
[
updateMixin
],
mixins
:
[
updateMixin
],
props
:
{
props
:
{
formState
:
{
formState
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/form.vue
View file @
9867eaf3
<
script
>
<
script
>
import
lockedWarning
from
'
./locked_warning.vue
'
;
import
lockedWarning
from
'
./locked_warning.vue
'
;
import
titleField
from
'
./fields/title.vue
'
;
import
titleField
from
'
./fields/title.vue
'
;
import
descriptionField
from
'
./fields/description.vue
'
;
import
descriptionField
from
'
./fields/description.vue
'
;
import
editActions
from
'
./edit_actions.vue
'
;
import
editActions
from
'
./edit_actions.vue
'
;
import
descriptionTemplate
from
'
./fields/description_template.vue
'
;
import
descriptionTemplate
from
'
./fields/description_template.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
lockedWarning
,
lockedWarning
,
titleField
,
titleField
,
descriptionField
,
descriptionField
,
descriptionTemplate
,
descriptionTemplate
,
editActions
,
editActions
,
},
props
:
{
canDestroy
:
{
type
:
Boolean
,
required
:
true
,
},
},
props
:
{
formState
:
{
canDestroy
:
{
type
:
Object
,
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
formState
:
{
type
:
Object
,
required
:
true
,
},
issuableTemplates
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
issuableType
:
{
type
:
String
,
required
:
true
,
},
markdownPreviewPath
:
{
type
:
String
,
required
:
true
,
},
markdownDocsPath
:
{
type
:
String
,
required
:
true
,
},
markdownVersion
:
{
type
:
Number
,
required
:
false
,
default
:
0
,
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
showDeleteButton
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
canAttachFile
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
enableAutocomplete
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
},
computed
:
{
issuableTemplates
:
{
hasIssuableTemplates
()
{
type
:
Array
,
return
this
.
issuableTemplates
.
length
;
required
:
false
,
}
,
default
:
()
=>
[]
,
},
},
};
issuableType
:
{
type
:
String
,
required
:
true
,
},
markdownPreviewPath
:
{
type
:
String
,
required
:
true
,
},
markdownDocsPath
:
{
type
:
String
,
required
:
true
,
},
markdownVersion
:
{
type
:
Number
,
required
:
false
,
default
:
0
,
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
projectNamespace
:
{
type
:
String
,
required
:
true
,
},
showDeleteButton
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
canAttachFile
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
enableAutocomplete
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
computed
:
{
hasIssuableTemplates
()
{
return
this
.
issuableTemplates
.
length
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/components/locked_warning.vue
View file @
9867eaf3
<
script
>
<
script
>
export
default
{
export
default
{
computed
:
{
computed
:
{
currentPath
()
{
currentPath
()
{
return
window
.
location
.
pathname
;
return
window
.
location
.
pathname
;
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/issue_show/stores/index.js
View file @
9867eaf3
...
@@ -25,8 +25,10 @@ export default class Store {
...
@@ -25,8 +25,10 @@ export default class Store {
}
}
stateShouldUpdate
(
data
)
{
stateShouldUpdate
(
data
)
{
return
this
.
state
.
titleText
!==
data
.
title_text
||
return
(
this
.
state
.
descriptionText
!==
data
.
description_text
;
this
.
state
.
titleText
!==
data
.
title_text
||
this
.
state
.
descriptionText
!==
data
.
description_text
);
}
}
setFormState
(
state
)
{
setFormState
(
state
)
{
...
...
app/assets/javascripts/jobs/components/artifacts_block.vue
View file @
9867eaf3
<
script
>
<
script
>
import
TimeagoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
TimeagoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
export
default
{
export
default
{
components
:
{
components
:
{
TimeagoTooltip
,
TimeagoTooltip
,
},
mixins
:
[
timeagoMixin
],
props
:
{
artifact
:
{
type
:
Object
,
required
:
true
,
},
},
mixins
:
[
},
timeagoMixin
,
computed
:
{
],
isExpired
()
{
props
:
{
return
this
.
artifact
.
expired
;
artifact
:
{
type
:
Object
,
required
:
true
,
},
},
},
computed
:
{
// Only when the key is `false` we can render this block
isExpired
()
{
willExpire
()
{
return
this
.
artifact
.
expired
;
return
this
.
artifact
.
expired
===
false
;
},
// Only when the key is `false` we can render this block
willExpire
()
{
return
this
.
artifact
.
expired
===
false
;
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"block"
>
<div
class=
"block"
>
...
...
app/assets/javascripts/jobs/components/commit_block.vue
View file @
9867eaf3
<
script
>
<
script
>
import
ClipboardButton
from
'
~/vue_shared/components/clipboard_button.vue
'
;
import
ClipboardButton
from
'
~/vue_shared/components/clipboard_button.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
ClipboardButton
,
ClipboardButton
,
},
props
:
{
commit
:
{
type
:
Object
,
required
:
true
,
},
},
props
:
{
mergeRequest
:
{
commit
:
{
type
:
Object
,
type
:
Object
,
required
:
false
,
required
:
true
,
default
:
null
,
},
mergeRequest
:
{
type
:
Object
,
required
:
false
,
default
:
null
,
},
isLastBlock
:
{
type
:
Boolean
,
required
:
true
,
},
},
},
};
isLastBlock
:
{
type
:
Boolean
,
required
:
true
,
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
<div
...
...
app/assets/javascripts/jobs/components/empty_state.vue
View file @
9867eaf3
<
script
>
<
script
>
export
default
{
export
default
{
props
:
{
props
:
{
illustrationPath
:
{
illustrationPath
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
illustrationSizeClass
:
{
illustrationSizeClass
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
title
:
{
title
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
content
:
{
content
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
default
:
null
,
default
:
null
,
},
},
action
:
{
action
:
{
type
:
Object
,
type
:
Object
,
required
:
false
,
required
:
false
,
default
:
null
,
default
:
null
,
validator
(
value
)
{
validator
(
value
)
{
return
(
return
(
value
===
null
||
value
===
null
||
(
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
path
'
)
&&
(
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
path
'
)
&&
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
method
'
)
&&
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
method
'
)
&&
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
button_title
'
))
Object
.
prototype
.
hasOwnProperty
.
call
(
value
,
'
button_title
'
))
);
);
},
},
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"row empty-state"
>
<div
class=
"row empty-state"
>
...
...
app/assets/javascripts/jobs/components/environments_block.vue
View file @
9867eaf3
<
script
>
<
script
>
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
{
sprintf
,
__
}
from
'
../../locale
'
;
import
{
sprintf
,
__
}
from
'
../../locale
'
;
export
default
{
export
default
{
components
:
{
components
:
{
CiIcon
,
CiIcon
,
},
props
:
{
deploymentStatus
:
{
type
:
Object
,
required
:
true
,
},
},
props
:
{
iconStatus
:
{
deploymentStatus
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
iconStatus
:
{
type
:
Object
,
required
:
true
,
},
},
},
computed
:
{
},
environment
()
{
computed
:
{
let
environmentText
;
environment
()
{
switch
(
this
.
deploymentStatus
.
status
)
{
let
environmentText
;
case
'
last
'
:
switch
(
this
.
deploymentStatus
.
status
)
{
case
'
last
'
:
environmentText
=
sprintf
(
__
(
'
This job is the most recent deployment to %{link}.
'
),
{
link
:
this
.
environmentLink
},
false
,
);
break
;
case
'
out_of_date
'
:
if
(
this
.
hasLastDeployment
)
{
environmentText
=
sprintf
(
environmentText
=
sprintf
(
__
(
'
This job is the most recent deployment to %{link}.
'
),
__
(
{
link
:
this
.
environmentLink
},
'
This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}.
'
,
),
{
environmentLink
:
this
.
environmentLink
,
deploymentLink
:
this
.
deploymentLink
(
`#
${
this
.
lastDeployment
.
iid
}
`
),
},
false
,
false
,
);
);
break
;
}
else
{
case
'
out_of_date
'
:
if
(
this
.
hasLastDeployment
)
{
environmentText
=
sprintf
(
__
(
'
This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}.
'
,
),
{
environmentLink
:
this
.
environmentLink
,
deploymentLink
:
this
.
deploymentLink
(
`#
${
this
.
lastDeployment
.
iid
}
`
),
},
false
,
);
}
else
{
environmentText
=
sprintf
(
__
(
'
This job is an out-of-date deployment to %{environmentLink}.
'
),
{
environmentLink
:
this
.
environmentLink
},
false
,
);
}
break
;
case
'
failed
'
:
environmentText
=
sprintf
(
environmentText
=
sprintf
(
__
(
'
Th
e deployment of this job to %{environmentLink} did not succeed
.
'
),
__
(
'
Th
is job is an out-of-date deployment to %{environmentLink}
.
'
),
{
environmentLink
:
this
.
environmentLink
},
{
environmentLink
:
this
.
environmentLink
},
false
,
false
,
);
);
break
;
}
case
'
creating
'
:
if
(
this
.
hasLastDeployment
)
{
break
;
environmentText
=
sprintf
(
case
'
failed
'
:
__
(
environmentText
=
sprintf
(
'
This job is creating a deployment to %{environmentLink} and will overwrite the %{deploymentLink}.
'
,
__
(
'
The deployment of this job to %{environmentLink} did not succeed.
'
),
),
{
environmentLink
:
this
.
environmentLink
},
{
environmentLink
:
this
.
environmentLink
,
deploymentLink
:
this
.
deploymentLink
(
__
(
'
latest deployment
'
)),
},
false
,
);
}
else
{
environmentText
=
sprintf
(
__
(
'
This job is creating a deployment to %{environmentLink}.
'
),
{
environmentLink
:
this
.
environmentLink
},
false
,
);
}
break
;
default
:
break
;
}
return
environmentText
;
},
environmentLink
()
{
if
(
this
.
hasEnvironment
)
{
return
sprintf
(
'
%{startLink}%{name}%{endLink}
'
,
{
startLink
:
`<a href="
${
this
.
deploymentStatus
.
environment
.
environment_path
}
" class="js-environment-link">`
,
name
:
_
.
escape
(
this
.
deploymentStatus
.
environment
.
name
),
endLink
:
'
</a>
'
,
},
false
,
false
,
);
);
}
break
;
return
''
;
case
'
creating
'
:
},
if
(
this
.
hasLastDeployment
)
{
hasLastDeployment
()
{
environmentText
=
sprintf
(
return
this
.
hasEnvironment
&&
this
.
deploymentStatus
.
environment
.
last_deployment
;
__
(
},
'
This job is creating a deployment to %{environmentLink} and will overwrite the %{deploymentLink}.
'
,
lastDeployment
()
{
),
return
this
.
hasLastDeployment
?
this
.
deploymentStatus
.
environment
.
last_deployment
:
{};
{
},
environmentLink
:
this
.
environmentLink
,
hasEnvironment
()
{
deploymentLink
:
this
.
deploymentLink
(
__
(
'
latest deployment
'
)),
return
!
_
.
isEmpty
(
this
.
deploymentStatus
.
environment
);
},
},
false
,
lastDeploymentPath
()
{
);
return
!
_
.
isEmpty
(
this
.
lastDeployment
.
deployable
)
?
this
.
lastDeployment
.
deployable
.
build_path
:
''
;
}
else
{
},
environmentText
=
sprintf
(
__
(
'
This job is creating a deployment to %{environmentLink}.
'
),
{
environmentLink
:
this
.
environmentLink
},
false
,
);
}
break
;
default
:
break
;
}
return
environmentText
;
},
},
methods
:
{
environmentLink
()
{
deploymentLink
(
name
)
{
if
(
this
.
hasEnvironment
)
{
return
sprintf
(
return
sprintf
(
'
%{startLink}%{name}%{endLink}
'
,
'
%{startLink}%{name}%{endLink}
'
,
{
{
startLink
:
`<a href="
${
this
.
lastDeploymentPath
}
" class="js-job-deployment-link">`
,
startLink
:
`<a href="
${
name
,
this
.
deploymentStatus
.
environment
.
environment_path
}
" class="js-environment-link">`
,
name
:
_
.
escape
(
this
.
deploymentStatus
.
environment
.
name
),
endLink
:
'
</a>
'
,
endLink
:
'
</a>
'
,
},
},
false
,
false
,
);
);
},
}
return
''
;
},
hasLastDeployment
()
{
return
this
.
hasEnvironment
&&
this
.
deploymentStatus
.
environment
.
last_deployment
;
},
lastDeployment
()
{
return
this
.
hasLastDeployment
?
this
.
deploymentStatus
.
environment
.
last_deployment
:
{};
},
hasEnvironment
()
{
return
!
_
.
isEmpty
(
this
.
deploymentStatus
.
environment
);
},
lastDeploymentPath
()
{
return
!
_
.
isEmpty
(
this
.
lastDeployment
.
deployable
)
?
this
.
lastDeployment
.
deployable
.
build_path
:
''
;
},
},
methods
:
{
deploymentLink
(
name
)
{
return
sprintf
(
'
%{startLink}%{name}%{endLink}
'
,
{
startLink
:
`<a href="
${
this
.
lastDeploymentPath
}
" class="js-job-deployment-link">`
,
name
,
endLink
:
'
</a>
'
,
},
false
,
);
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"prepend-top-default js-environment-container"
>
<div
class=
"prepend-top-default js-environment-container"
>
...
...
app/assets/javascripts/jobs/components/erased_block.vue
View file @
9867eaf3
<
script
>
<
script
>
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
TimeagoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
TimeagoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
TimeagoTooltip
,
TimeagoTooltip
,
},
props
:
{
user
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({}),
},
},
props
:
{
erasedAt
:
{
user
:
{
type
:
String
,
type
:
Object
,
required
:
true
,
required
:
false
,
default
:
()
=>
({}),
},
erasedAt
:
{
type
:
String
,
required
:
true
,
},
},
},
computed
:
{
},
isErasedByUser
()
{
computed
:
{
return
!
_
.
isEmpty
(
this
.
user
);
isErasedByUser
()
{
},
return
!
_
.
isEmpty
(
this
.
user
);
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"prepend-top-default js-build-erased"
>
<div
class=
"prepend-top-default js-build-erased"
>
...
...
app/assets/javascripts/jobs/components/job_log.vue
View file @
9867eaf3
<
script
>
<
script
>
export
default
{
export
default
{
name
:
'
JobLog
'
,
name
:
'
JobLog
'
,
props
:
{
props
:
{
trace
:
{
trace
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
isComplete
:
{
type
:
Boolean
,
required
:
true
,
},
},
},
};
isComplete
:
{
type
:
Boolean
,
required
:
true
,
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<pre
class=
"build-trace"
>
<pre
class=
"build-trace"
>
...
...
app/assets/javascripts/jobs/components/job_log_controllers.vue
View file @
9867eaf3
<
script
>
<
script
>
import
{
polyfillSticky
}
from
'
~/lib/utils/sticky
'
;
import
{
polyfillSticky
}
from
'
~/lib/utils/sticky
'
;
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
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
{
sprintf
}
from
'
~/locale
'
;
export
default
{
export
default
{
components
:
{
components
:
{
Icon
,
Icon
,
},
directives
:
{
tooltip
,
},
props
:
{
erasePath
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
},
directives
:
{
size
:
{
tooltip
,
type
:
Number
,
required
:
true
,
},
},
props
:
{
rawPath
:
{
erasePath
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
default
:
null
,
default
:
null
,
},
size
:
{
type
:
Number
,
required
:
true
,
},
rawPath
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
isScrollTopDisabled
:
{
type
:
Boolean
,
required
:
true
,
},
isScrollBottomDisabled
:
{
type
:
Boolean
,
required
:
true
,
},
isScrollingDown
:
{
type
:
Boolean
,
required
:
true
,
},
isTraceSizeVisible
:
{
type
:
Boolean
,
required
:
true
,
},
},
},
computed
:
{
isScrollTopDisabled
:
{
jobLogSize
()
{
type
:
Boolean
,
return
sprintf
(
'
Showing last %{size} of log -
'
,
{
required
:
true
,
size
:
numberToHumanSize
(
this
.
size
),
});
},
},
},
mounted
()
{
isScrollBottomDisabled
:
{
polyfillSticky
(
this
.
$el
);
type
:
Boolean
,
required
:
true
,
},
},
methods
:
{
isScrollingDown
:
{
handleScrollToTop
()
{
type
:
Boolean
,
this
.
$emit
(
'
scrollJobLogTop
'
);
required
:
true
,
},
handleScrollToBottom
()
{
this
.
$emit
(
'
scrollJobLogBottom
'
);
},
},
},
isTraceSizeVisible
:
{
};
type
:
Boolean
,
required
:
true
,
},
},
computed
:
{
jobLogSize
()
{
return
sprintf
(
'
Showing last %{size} of log -
'
,
{
size
:
numberToHumanSize
(
this
.
size
),
});
},
},
mounted
()
{
polyfillSticky
(
this
.
$el
);
},
methods
:
{
handleScrollToTop
()
{
this
.
$emit
(
'
scrollJobLogTop
'
);
},
handleScrollToBottom
()
{
this
.
$emit
(
'
scrollJobLogBottom
'
);
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"top-bar"
>
<div
class=
"top-bar"
>
...
...
app/assets/javascripts/jobs/components/jobs_container.vue
View file @
9867eaf3
<
script
>
<
script
>
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_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
{
components
:
{
components
:
{
CiIcon
,
CiIcon
,
Icon
,
Icon
,
},
directives
:
{
tooltip
,
},
props
:
{
jobs
:
{
type
:
Array
,
required
:
true
,
},
},
directives
:
{
jobId
:
{
tooltip
,
type
:
Number
,
required
:
true
,
},
},
props
:
{
},
jobs
:
{
methods
:
{
type
:
Array
,
isJobActive
(
currentJobId
)
{
required
:
true
,
return
this
.
jobId
===
currentJobId
;
},
jobId
:
{
type
:
Number
,
required
:
true
,
},
},
},
methods
:
{
tooltipText
(
job
)
{
isJobActive
(
currentJobId
)
{
return
`
${
_
.
escape
(
job
.
name
)}
-
${
job
.
status
.
tooltip
}
`
;
return
this
.
jobId
===
currentJobId
;
},
tooltipText
(
job
)
{
return
`
${
_
.
escape
(
job
.
name
)}
-
${
job
.
status
.
tooltip
}
`
;
},
},
},
};
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"js-jobs-container builds-container"
>
<div
class=
"js-jobs-container builds-container"
>
...
...
app/assets/javascripts/jobs/components/sidebar.vue
View file @
9867eaf3
<
script
>
<
script
>
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
{
timeIntervalInWords
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
timeIntervalInWords
}
from
'
~/lib/utils/datetime_utility
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
DetailRow
from
'
./sidebar_detail_row.vue
'
;
import
DetailRow
from
'
./sidebar_detail_row.vue
'
;
import
ArtifactsBlock
from
'
./artifacts_block.vue
'
;
import
ArtifactsBlock
from
'
./artifacts_block.vue
'
;
import
TriggerBlock
from
'
./trigger_block.vue
'
;
import
TriggerBlock
from
'
./trigger_block.vue
'
;
import
CommitBlock
from
'
./commit_block.vue
'
;
import
CommitBlock
from
'
./commit_block.vue
'
;
import
StagesDropdown
from
'
./stages_dropdown.vue
'
;
import
StagesDropdown
from
'
./stages_dropdown.vue
'
;
import
JobsContainer
from
'
./jobs_container.vue
'
;
import
JobsContainer
from
'
./jobs_container.vue
'
;
export
default
{
export
default
{
name
:
'
JobSidebar
'
,
name
:
'
JobSidebar
'
,
components
:
{
components
:
{
ArtifactsBlock
,
ArtifactsBlock
,
CommitBlock
,
CommitBlock
,
DetailRow
,
DetailRow
,
Icon
,
Icon
,
TriggerBlock
,
TriggerBlock
,
StagesDropdown
,
StagesDropdown
,
JobsContainer
,
JobsContainer
,
},
mixins
:
[
timeagoMixin
],
props
:
{
runnerHelpUrl
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
mixins
:
[
timeagoMixin
],
terminalPath
:
{
props
:
{
type
:
String
,
runnerHelpUrl
:
{
required
:
false
,
type
:
String
,
default
:
null
,
required
:
false
,
default
:
''
,
},
terminalPath
:
{
type
:
String
,
required
:
false
,
default
:
null
,
},
},
},
computed
:
{
},
...
mapState
([
'
job
'
,
'
isLoading
'
,
'
stages
'
,
'
jobs
'
]),
computed
:
{
coverage
()
{
...
mapState
([
'
job
'
,
'
isLoading
'
,
'
stages
'
,
'
jobs
'
]),
return
`
${
this
.
job
.
coverage
}
%`
;
coverage
()
{
},
return
`
${
this
.
job
.
coverage
}
%`
;
duration
()
{
},
return
timeIntervalInWords
(
this
.
job
.
duration
);
duration
()
{
},
return
timeIntervalInWords
(
this
.
job
.
duration
);
queued
()
{
},
return
timeIntervalInWords
(
this
.
job
.
queued
);
queued
()
{
},
return
timeIntervalInWords
(
this
.
job
.
queued
);
runnerId
()
{
},
return
`
${
this
.
job
.
runner
.
description
}
(#
${
this
.
job
.
runner
.
id
}
)`
;
runnerId
()
{
},
return
`
${
this
.
job
.
runner
.
description
}
(#
${
this
.
job
.
runner
.
id
}
)`
;
retryButtonClass
()
{
},
let
className
=
retryButtonClass
()
{
'
js-retry-button float-right btn btn-retry d-none d-md-block d-lg-block d-xl-block
'
;
let
className
=
className
+=
'
js-retry-button float-right btn btn-retry d-none d-md-block d-lg-block d-xl-block
'
;
this
.
job
.
status
&&
this
.
job
.
recoverable
?
'
btn-primary
'
:
'
btn-inverted-secondary
'
;
className
+=
return
className
;
this
.
job
.
status
&&
this
.
job
.
recoverable
?
'
btn-primary
'
:
'
btn-inverted-secondary
'
;
},
return
className
;
hasTimeout
()
{
},
return
this
.
job
.
metadata
!=
null
&&
this
.
job
.
metadata
.
timeout_human_readable
!==
null
;
hasTimeout
()
{
},
return
this
.
job
.
metadata
!=
null
&&
this
.
job
.
metadata
.
timeout_human_readable
!==
null
;
timeout
()
{
},
if
(
this
.
job
.
metadata
==
null
)
{
timeout
()
{
return
''
;
if
(
this
.
job
.
metadata
==
null
)
{
}
return
''
;
}
let
t
=
this
.
job
.
metadata
.
timeout_human_readable
;
let
t
=
this
.
job
.
metadata
.
timeout_human_readable
;
if
(
this
.
job
.
metadata
.
timeout_source
!==
''
)
{
if
(
this
.
job
.
metadata
.
timeout_source
!==
''
)
{
t
+=
` (from
${
this
.
job
.
metadata
.
timeout_source
}
)`
;
t
+=
` (from
${
this
.
job
.
metadata
.
timeout_source
}
)`
;
}
}
return
t
;
return
t
;
},
},
renderBlock
()
{
renderBlock
()
{
return
(
return
(
this
.
job
.
merge_request
||
this
.
job
.
merge_request
||
this
.
job
.
duration
||
this
.
job
.
duration
||
this
.
job
.
finished_data
||
this
.
job
.
finished_data
||
this
.
job
.
erased_at
||
this
.
job
.
erased_at
||
this
.
job
.
queued
||
this
.
job
.
queued
||
this
.
job
.
runner
||
this
.
job
.
runner
||
this
.
job
.
coverage
||
this
.
job
.
coverage
||
this
.
job
.
tags
.
length
||
this
.
job
.
tags
.
length
||
this
.
job
.
cancel_path
this
.
job
.
cancel_path
);
);
},
},
hasArtifact
()
{
hasArtifact
()
{
return
!
_
.
isEmpty
(
this
.
job
.
artifact
);
return
!
_
.
isEmpty
(
this
.
job
.
artifact
);
},
},
hasTriggers
()
{
hasTriggers
()
{
return
!
_
.
isEmpty
(
this
.
job
.
trigger
);
return
!
_
.
isEmpty
(
this
.
job
.
trigger
);
},
},
hasStages
()
{
hasStages
()
{
return
(
return
(
(
this
.
job
&&
(
this
.
job
&&
this
.
job
.
pipeline
&&
this
.
job
.
pipeline
&&
this
.
job
.
pipeline
.
stages
&&
this
.
job
.
pipeline
.
stages
&&
this
.
job
.
pipeline
.
stages
.
length
>
0
)
||
this
.
job
.
pipeline
.
stages
.
length
>
0
)
||
false
false
);
);
},
commit
()
{
return
this
.
job
.
pipeline
.
commit
||
{};
},
},
},
methods
:
{
commit
()
{
...
mapActions
([
'
fetchJobsForStage
'
]),
return
this
.
job
.
pipeline
.
commit
||
{};
},
},
};
},
methods
:
{
...
mapActions
([
'
fetchJobsForStage
'
]),
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<aside
<aside
...
...
app/assets/javascripts/jobs/components/sidebar_detail_row.vue
View file @
9867eaf3
<
script
>
<
script
>
export
default
{
export
default
{
name
:
'
SidebarDetailRow
'
,
name
:
'
SidebarDetailRow
'
,
props
:
{
props
:
{
title
:
{
title
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
default
:
''
,
default
:
''
,
},
value
:
{
type
:
String
,
required
:
true
,
},
helpUrl
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
},
computed
:
{
value
:
{
hasTitle
()
{
type
:
String
,
return
this
.
title
.
length
>
0
;
required
:
true
,
},
hasHelpURL
()
{
return
this
.
helpUrl
.
length
>
0
;
},
},
},
};
helpUrl
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
computed
:
{
hasTitle
()
{
return
this
.
title
.
length
>
0
;
},
hasHelpURL
()
{
return
this
.
helpUrl
.
length
>
0
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<p
class=
"build-detail-row"
>
<p
class=
"build-detail-row"
>
...
...
app/assets/javascripts/jobs/components/stages_dropdown.vue
View file @
9867eaf3
<
script
>
<
script
>
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
__
}
from
'
~/locale
'
;
export
default
{
export
default
{
components
:
{
components
:
{
CiIcon
,
CiIcon
,
Icon
,
Icon
,
},
props
:
{
pipeline
:
{
type
:
Object
,
required
:
true
,
},
},
props
:
{
stages
:
{
pipeline
:
{
type
:
Array
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
stages
:
{
type
:
Array
,
required
:
true
,
},
},
},
data
()
{
},
return
{
data
()
{
selectedStage
:
this
.
stages
.
length
>
0
?
this
.
stages
[
0
].
name
:
__
(
'
More
'
),
return
{
};
selectedStage
:
this
.
stages
.
length
>
0
?
this
.
stages
[
0
].
name
:
__
(
'
More
'
),
};
},
computed
:
{
hasRef
()
{
return
!
_
.
isEmpty
(
this
.
pipeline
.
ref
);
},
},
computed
:
{
},
hasRef
()
{
watch
:
{
return
!
_
.
isEmpty
(
this
.
pipeline
.
ref
);
// When the component is initially mounted it may start with an empty stages array.
},
// Once the prop is updated, we set the first stage as the selected one
stages
(
newVal
)
{
if
(
newVal
.
length
)
{
this
.
selectedStage
=
newVal
[
0
].
name
;
}
},
},
watch
:
{
},
// When the component is initially mounted it may start with an empty stages array.
methods
:
{
// Once the prop is updated, we set the first stage as the selected one
onStageClick
(
stage
)
{
stages
(
newVal
)
{
this
.
$emit
(
'
requestSidebarStageDropdown
'
,
stage
);
if
(
newVal
.
length
)
{
this
.
selectedStage
=
stage
.
name
;
this
.
selectedStage
=
newVal
[
0
].
name
;
}
},
},
},
methods
:
{
},
onStageClick
(
stage
)
{
};
this
.
$emit
(
'
requestSidebarStageDropdown
'
,
stage
);
this
.
selectedStage
=
stage
.
name
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"block-last dropdown"
>
<div
class=
"block-last dropdown"
>
...
...
app/assets/javascripts/jobs/components/trigger_block.vue
View file @
9867eaf3
<
script
>
<
script
>
export
default
{
export
default
{
props
:
{
props
:
{
trigger
:
{
trigger
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
},
data
()
{
},
return
{
data
()
{
areVariablesVisible
:
false
,
return
{
};
areVariablesVisible
:
false
,
};
},
computed
:
{
hasVariables
()
{
return
this
.
trigger
.
variables
&&
this
.
trigger
.
variables
.
length
>
0
;
},
},
computed
:
{
},
hasVariables
()
{
methods
:
{
return
this
.
trigger
.
variables
&&
this
.
trigger
.
variables
.
length
>
0
;
revealVariables
()
{
},
this
.
areVariablesVisible
=
true
;
},
},
methods
:
{
},
revealVariables
()
{
};
this
.
areVariablesVisible
=
true
;
},
},
};
</
script
>
</
script
>
<
template
>
<
template
>
...
...
app/assets/javascripts/jobs/store/index.js
View file @
9867eaf3
...
@@ -7,9 +7,10 @@ import mutations from './mutations';
...
@@ -7,9 +7,10 @@ import mutations from './mutations';
Vue
.
use
(
Vuex
);
Vue
.
use
(
Vuex
);
export
default
()
=>
new
Vuex
.
Store
({
export
default
()
=>
actions
,
new
Vuex
.
Store
({
mutations
,
actions
,
getters
,
mutations
,
state
:
state
(),
getters
,
});
state
:
state
(),
});
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