2018-11-20 20:47:30 +05:30
< script >
2022-08-13 15:12:31 +05:30
import { GlTooltipDirective , GlLink , GlButton , GlSearchBoxByClick } from '@gitlab/ui' ;
import { scrollToElement } from '~/lib/utils/common_utils' ;
2018-12-13 13:39:08 +05:30
import { numberToHumanSize } from '~/lib/utils/number_utils' ;
2021-04-29 21:17:54 +05:30
import { _ _ , s _ _ , sprintf } from '~/locale' ;
2022-08-13 15:12:31 +05:30
import HelpPopover from '~/vue_shared/components/help_popover.vue' ;
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin' ;
2018-11-20 20:47:30 +05:30
2018-12-13 13:39:08 +05:30
export default {
2021-04-29 21:17:54 +05:30
i18n : {
scrollToBottomButtonLabel : s _ _ ( 'Job|Scroll to bottom' ) ,
scrollToTopButtonLabel : s _ _ ( 'Job|Scroll to top' ) ,
showRawButtonLabel : s _ _ ( 'Job|Show complete raw' ) ,
2022-08-13 15:12:31 +05:30
searchPlaceholder : s _ _ ( 'Job|Search job log' ) ,
noResults : s _ _ ( 'Job|No search results found' ) ,
searchPopoverTitle : s _ _ ( 'Job|Job log search' ) ,
searchPopoverDescription : s _ _ (
'Job|Search for substrings in your job log output. Currently search is only supported for the visible job log output, not for any log output that is truncated due to size.' ,
) ,
logLineNumberNotFound : s _ _ ( 'Job|We could not find this element' ) ,
2021-04-29 21:17:54 +05:30
} ,
2018-12-13 13:39:08 +05:30
components : {
GlLink ,
2020-11-24 15:15:51 +05:30
GlButton ,
2022-08-13 15:12:31 +05:30
GlSearchBoxByClick ,
HelpPopover ,
2018-12-13 13:39:08 +05:30
} ,
directives : {
GlTooltip : GlTooltipDirective ,
} ,
2022-08-13 15:12:31 +05:30
mixins : [ glFeatureFlagMixin ( ) ] ,
2018-12-13 13:39:08 +05:30
props : {
size : {
type : Number ,
required : true ,
2018-11-20 20:47:30 +05:30
} ,
2018-12-13 13:39:08 +05:30
rawPath : {
type : String ,
required : false ,
default : null ,
2018-11-20 20:47:30 +05:30
} ,
2018-12-13 13:39:08 +05:30
isScrollTopDisabled : {
type : Boolean ,
required : true ,
2018-11-20 20:47:30 +05:30
} ,
2018-12-13 13:39:08 +05:30
isScrollBottomDisabled : {
type : Boolean ,
required : true ,
2018-12-05 23:21:45 +05:30
} ,
2018-12-13 13:39:08 +05:30
isScrollingDown : {
type : Boolean ,
required : true ,
2018-11-20 20:47:30 +05:30
} ,
2021-11-18 22:05:49 +05:30
isJobLogSizeVisible : {
2018-12-13 13:39:08 +05:30
type : Boolean ,
required : true ,
} ,
2022-08-13 15:12:31 +05:30
jobLog : {
type : Array ,
required : true ,
} ,
} ,
data ( ) {
return {
searchTerm : '' ,
searchResults : [ ] ,
} ;
2018-12-13 13:39:08 +05:30
} ,
computed : {
jobLogSize ( ) {
2019-09-30 21:07:59 +05:30
return sprintf ( _ _ ( 'Showing last %{size} of log -' ) , {
2018-12-13 13:39:08 +05:30
size : numberToHumanSize ( this . size ) ,
} ) ;
} ,
2022-08-13 15:12:31 +05:30
showJobLogSearch ( ) {
return this . glFeatures . jobLogSearch ;
} ,
2018-12-13 13:39:08 +05:30
} ,
methods : {
handleScrollToTop ( ) {
this . $emit ( 'scrollJobLogTop' ) ;
} ,
handleScrollToBottom ( ) {
this . $emit ( 'scrollJobLogBottom' ) ;
} ,
2022-08-13 15:12:31 +05:30
searchJobLog ( ) {
this . searchResults = [ ] ;
if ( ! this . searchTerm ) return ;
const compactedLog = [ ] ;
this . jobLog . forEach ( ( obj ) => {
if ( obj . lines && obj . lines . length > 0 ) {
compactedLog . push ( ... obj . lines ) ;
}
if ( ! obj . lines && obj . content . length > 0 ) {
compactedLog . push ( obj ) ;
}
} ) ;
compactedLog . forEach ( ( line ) => {
const lineText = line . content [ 0 ] . text ;
if ( lineText . toLocaleLowerCase ( ) . includes ( this . searchTerm . toLocaleLowerCase ( ) ) ) {
this . searchResults . push ( line ) ;
}
} ) ;
if ( this . searchResults . length > 0 ) {
this . $emit ( 'searchResults' , this . searchResults ) ;
// BE returns zero based index, we need to add one to match the line numbers in the DOM
const firstSearchResult = ` #L ${ this . searchResults [ 0 ] . lineNumber + 1 } ` ;
const logLine = document . querySelector ( ` .js-line ${ firstSearchResult } ` ) ;
if ( logLine ) {
setTimeout ( ( ) => scrollToElement ( logLine ) ) ;
const message = sprintf ( s _ _ ( 'Job|%{searchLength} results found for %{searchTerm}' ) , {
searchLength : this . searchResults . length ,
searchTerm : this . searchTerm ,
} ) ;
this . $toast . show ( message ) ;
} else {
this . $toast . show ( this . $options . i18n . logLineNumberNotFound ) ;
}
} else {
this . $toast . show ( this . $options . i18n . noResults ) ;
}
} ,
2018-12-13 13:39:08 +05:30
} ,
} ;
2018-11-20 20:47:30 +05:30
< / script >
< template >
2018-12-13 13:39:08 +05:30
< div class = "top-bar" >
2018-11-20 20:47:30 +05:30
<!-- truncate information -- >
2021-06-08 01:23:25 +05:30
< div
class = "truncated-info gl-display-none gl-sm-display-block gl-float-left"
data - testid = "log-truncated-info"
>
2021-11-18 22:05:49 +05:30
< template v-if = "isJobLogSizeVisible" >
2018-12-05 23:21:45 +05:30
{ { jobLogSize } }
2019-07-31 22:56:46 +05:30
< gl-link
v - if = "rawPath"
: href = "rawPath"
2020-10-24 23:57:45 +05:30
class = "text-plain text-underline gl-ml-2"
data - testid = "raw-link"
2019-09-30 21:07:59 +05:30
> { { s _ _ ( 'Job|Complete Raw' ) } } < / g l - l i n k
2019-07-31 22:56:46 +05:30
>
2018-12-05 23:21:45 +05:30
< / template >
2018-11-20 20:47:30 +05:30
< / div >
<!-- eo truncate information -- >
2021-06-08 01:23:25 +05:30
< div class = "controllers gl-float-right" >
2022-08-13 15:12:31 +05:30
< template v-if = "showJobLogSearch" >
< gl-search-box-by-click
v - model = "searchTerm"
class = "gl-mr-3"
: placeholder = "$options.i18n.searchPlaceholder"
data - testid = "job-log-search-box"
@ clear = "$emit('searchResults', [])"
@ submit = "searchJobLog"
/ >
< help-popover class = "gl-mr-3" >
< template # title > { { $options . i18n . searchPopoverTitle } } < / template >
< p class = "gl-mb-0" >
{ { $options . i18n . searchPopoverDescription } }
< / p >
< / help-popover >
< / template >
2018-11-20 20:47:30 +05:30
<!-- links -- >
2020-11-24 15:15:51 +05:30
< gl-button
2018-12-05 23:21:45 +05:30
v - if = "rawPath"
2018-12-13 13:39:08 +05:30
v - gl - tooltip . body
2021-04-29 21:17:54 +05:30
: title = "$options.i18n.showRawButtonLabel"
: aria - label = "$options.i18n.showRawButtonLabel"
2018-12-05 23:21:45 +05:30
: href = "rawPath"
2020-10-24 23:57:45 +05:30
data - testid = "job-raw-link-controller"
2020-11-24 15:15:51 +05:30
icon = "doc-text"
/ >
2018-11-20 20:47:30 +05:30
<!-- eo links -- >
<!-- scroll buttons -- >
2021-04-29 21:17:54 +05:30
< div v -gl -tooltip :title = "$options.i18n.scrollToTopButtonLabel" class = "gl-ml-3" >
2020-11-24 15:15:51 +05:30
< gl-button
2018-12-05 23:21:45 +05:30
: disabled = "isScrollTopDisabled"
2021-04-17 20:07:23 +05:30
class = "btn-scroll"
2020-10-24 23:57:45 +05:30
data - testid = "job-controller-scroll-top"
2020-11-24 15:15:51 +05:30
icon = "scroll_up"
2021-04-29 21:17:54 +05:30
: aria - label = "$options.i18n.scrollToTopButtonLabel"
2018-11-20 20:47:30 +05:30
@ click = "handleScrollToTop"
2020-11-24 15:15:51 +05:30
/ >
2018-11-20 20:47:30 +05:30
< / div >
2021-04-29 21:17:54 +05:30
< div v -gl -tooltip :title = "$options.i18n.scrollToBottomButtonLabel" class = "gl-ml-3" >
2020-11-24 15:15:51 +05:30
< gl-button
2018-12-05 23:21:45 +05:30
: disabled = "isScrollBottomDisabled"
2021-04-17 20:07:23 +05:30
class = "js-scroll-bottom btn-scroll"
2020-10-24 23:57:45 +05:30
data - testid = "job-controller-scroll-bottom"
2020-11-24 15:15:51 +05:30
icon = "scroll_down"
: class = "{ animate: isScrollingDown }"
2021-04-29 21:17:54 +05:30
: aria - label = "$options.i18n.scrollToBottomButtonLabel"
2018-11-20 20:47:30 +05:30
@ click = "handleScrollToBottom"
2018-12-13 13:39:08 +05:30
/ >
2018-11-20 20:47:30 +05:30
< / div >
<!-- eo scroll buttons -- >
< / div >
< / div >
< / template >