{"version":3,"sources":["webpack:///./vue_shared/components/local_storage_sync.vue?a4c7","webpack:///vue_shared/components/local_storage_sync.vue","webpack:///./vue_shared/components/local_storage_sync.vue","webpack:///./ci/pipeline_details/stores/test_reports/utils.js","webpack:///./lib/utils/number_utils.js","webpack:///./ci/pipeline_details/tabs/pipeline_tabs.vue?52f0","webpack:///ci/pipeline_details/tabs/pipeline_tabs.vue","webpack:///./ci/pipeline_details/tabs/pipeline_tabs.vue?a484","webpack:///./ci/pipeline_details/tabs/pipeline_tabs.vue","webpack:////build/source/ee/app/assets/javascripts/ci/pipeline_details/tabs/pipeline_tabs.vue?1e46","webpack:///../../../ee/app/assets/javascripts/ci/pipeline_details/tabs/pipeline_tabs.vue","webpack:////build/source/ee/app/assets/javascripts/ci/pipeline_details/tabs/pipeline_tabs.vue?1b79","webpack:////build/source/ee/app/assets/javascripts/ci/pipeline_details/tabs/pipeline_tabs.vue","webpack:///./ci/pipeline_details/stores/test_reports/mutation_types.js","webpack:///./ci/pipeline_details/stores/test_reports/actions.js","webpack:///./ci/pipeline_details/stores/test_reports/constants.js","webpack:///./ci/pipeline_details/stores/test_reports/getters.js","webpack:///./ci/pipeline_details/stores/test_reports/mutations.js","webpack:///./ci/pipeline_details/stores/test_reports/state.js","webpack:///./ci/pipeline_details/pipeline_tabs.js","webpack:///./ci/pipeline_details/stores/test_reports/index.js"],"names":["props","storageKey","type","String","required","value","Number","Boolean","Array","Object","default","asString","persist","clear","watch","newVal","saveValue","serialize","localStorage","removeItem","mounted","exists","getStorageValue","_isEqual","$emit","methods","getItem","deserialize","console","warn","val","setItem","_isString","JSON","stringify","parse","render","_this$$scopedSlots$de","_this$$scopedSlots","$scopedSlots","call","component","staticRenderFns","formatFilePath","file","replace","iconForTestStatus","status","testStatus","SUCCESS","FAILED","ERROR","SKIPPED","UNKNOWN","formattedTime","seconds","sprintf","__","milliseconds","toFixed","stringifyTime","parseSeconds","Math","floor","trim","addIconStatus","testCase","icon","execution_time","bytesToMiB","number","BYTES_IN_KIB","bytesToGiB","numberToHumanSizeSplit","size","digits","locale","abs","digitsOptions","minimumFractionDigits","maximumFractionDigits","formatNumberWithLocaleAndDigits","n","formatNumber","toString","numberToHumanSize","humanSize","label","numberToMetricPrefix","uppercase","THOUSAND","MILLION","median","arr","middle","length","sorted","sort","a","b","changeInPercent","firstY","lastY","round","formattedChangeInPercent","nonFiniteResult","change","isFinite","isNumeric","isNaN","parseInt","numberRegex","isPositiveInteger","test","countFloatingPointDigits","num","decimal","parts","split","integer","splitDecimalNumber","i18n","tabs","failedJobsTitle","jobsTitle","pipelineTitle","testsTitle","manualVariables","tabNames","pipeline","pipelineTabName","jobs","jobsTabName","failures","failedJobsTabName","tests","testReportTabName","manualVariablesTabName","components","GlBadge","GlTab","GlTabs","LocalStorageSync","mixins","Tracking","mixin","featureFlagMixin","inject","data","activeTab","defaultTabValue","isDismissedNewTab","computed","showFailedJobsTab","failedJobsCount","manualVariablesEnabled","glFeatures","ciShowManualVariablesInPipeline","manualVariablesCount","$route","to","name","isActive","tabName","navigateTo","$router","push","failedJobsTabClick","track","TRACKING_CATEGORIES","failed","$options","testsTabClick","manualVariablesTabClick","MANUAL_VARIABLE_TAB_DISMISS_STORAGE_KEY","_vm","this","_c","_self","ref","attrs","on","$event","_v","scopedSlots","_u","key","fn","staticClass","_s","totalJobCount","proxy","_e","testsCount","model","callback","$$v","expression","_t","securityTitle","codeQualityTitle","licensesTitle","security","securityTabName","licenses","licensesTabName","codeQuality","codeQualityTabName","BasePipelineTabs","sbomReportsErrors","codeQualityCount","undefined","codeQualityCountFetched","licenseCount","licenseScanCount","showCodeQualityTab","isFullCodequalityReportAvailable","codequalityReportDownloadPath","canGenerateCodequalityReports","showLicenseTab","exposeLicenseScanningData","showSecurityTab","exposeSecurityDashboard","showLicenseCount","navigateToSecurity","Api","trackRedisHllUserEvent","SERVICE_PING_PIPELINE_SECURITY_VISIT","updateCodeQualityCount","count","updateLicenseCount","licenseManagementApiUrl","licensesApiPath","securityPoliciesPath","canManageLicenses","fetchSummary","state","commit","dispatch","axios","get","summaryEndpoint","then","catch","createAlert","message","s__","finally","fetchTestSuite","index","_state$testReports","_state$testReports2","hasFullSuite","testReports","test_suites","Promise","resolve","build_ids","suiteEndpoint","params","suite","error","setPage","page","setSelectedSuiteIndex","removeSelectedSuiteIndex","toggleLoading","getTestSuites","testSuites","map","total_time","getSelectedSuite","selectedSuiteIndex","getSuiteTests","test_cases","testCases","perPage","pageInfo","start","classname","filePath","blobPath","slice","getSuiteTestCount","_getSelectedSuite","getSuiteArtifactsExpired","errorMessage","assign","_error$response","response","errors","total","time","total_count","success_count","success","failed_count","skipped_count","skipped","error_count","isLoading","Vue","use","GlToast","VueApollo","VueRouter","Vuex","createAppOptions","selector","apolloProvider","router","el","document","querySelector","dataset","codequalityBlobPath","codequalityProjectPath","downloadablePathForReportType","projectPath","graphqlResourceEtag","pipelineIid","pipelineProjectPath","hasTestReport","emptyStateImagePath","artifactsExpiredImagePath","canReadVariables","getPipelineDefaultTab","window","location","href","PipelineTabs","store","Store","modules","initialState","namespaced","actions","getters","mutations","provide","parseBoolean","createElement","createPipelineTabs","options"],"mappings":"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","file":"341.5308d8e1.chunk.js","sourcesContent":["import mod from \"-!../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./local_storage_sync.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./local_storage_sync.vue?vue&type=script&lang=js\"","<script>\nimport { isEqual, isString } from 'lodash';\n\n/**\n * This component will save and restore a value to and from localStorage.\n * The value will be saved only when the value changes; the initial value won't be saved.\n *\n * By default, the value will be saved using JSON.stringify(), and retrieved back using JSON.parse().\n *\n * If you would like to save the raw string instead, you may set the 'asString' prop to true, though be aware that this is a\n * legacy prop to maintain backwards compatibility.\n *\n * For new components saving data for the first time, it's recommended to not use 'asString' even if you're saving a string; it will still be\n * saved and restored properly using JSON.stringify()/JSON.parse().\n */\nexport default {\n props: {\n storageKey: {\n type: String,\n required: true,\n },\n value: {\n type: [String, Number, Boolean, Array, Object],\n required: false,\n default: '',\n },\n asString: {\n type: Boolean,\n required: false,\n default: false,\n },\n persist: {\n type: Boolean,\n required: false,\n default: true,\n },\n clear: {\n type: Boolean,\n required: false,\n default: false,\n },\n },\n watch: {\n value(newVal) {\n if (!this.persist) return;\n\n this.saveValue(this.serialize(newVal));\n },\n clear(newVal) {\n if (newVal) {\n localStorage.removeItem(this.storageKey);\n }\n },\n },\n mounted() {\n // On mount, trigger update if we actually have a localStorageValue\n const { exists, value } = this.getStorageValue();\n\n if (exists && !isEqual(value, this.value)) {\n this.$emit('input', value);\n }\n },\n methods: {\n getStorageValue() {\n const value = localStorage.getItem(this.storageKey);\n\n if (value === null) {\n return { exists: false };\n }\n\n try {\n return { exists: true, value: this.deserialize(value) };\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\n `[gitlab] Failed to deserialize value from localStorage (key=${this.storageKey})`,\n value,\n );\n // default to \"don't use localStorage value\"\n return { exists: false };\n }\n },\n saveValue(val) {\n localStorage.setItem(this.storageKey, val);\n },\n serialize(val) {\n if (!isString(val) && this.asString) {\n // eslint-disable-next-line no-console\n console.warn(\n `[gitlab] LocalStorageSync is saving`,\n val,\n `to the key \"${this.storageKey}\", but it is not a string and the 'asString' prop is true. This will save and restore the stringified value rather than the original value. If this is not intended, please remove or set the 'asString' prop to false.`,\n );\n }\n\n return this.asString ? val : JSON.stringify(val);\n },\n deserialize(val) {\n return this.asString ? val : JSON.parse(val);\n },\n },\n render() {\n return this.$scopedSlots.default?.();\n },\n};\n</script>\n","var render, staticRenderFns\nimport script from \"./local_storage_sync.vue?vue&type=script&lang=js\"\nexport * from \"./local_storage_sync.vue?vue&type=script&lang=js\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import { __, sprintf } from '~/locale';\nimport { parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility';\nimport { testStatus } from '../../constants';\n\n/**\n * Removes `./` from the beginning of a file path so it can be appended onto a blob path\n * @param {String} file\n * @returns {String} - formatted value\n */\nexport function formatFilePath(file) {\n return file.replace(/^\\.?\\/*/, '');\n}\n\nexport function iconForTestStatus(status) {\n switch (status) {\n case testStatus.SUCCESS:\n return 'status_success';\n case testStatus.FAILED:\n return 'status_failed';\n case testStatus.ERROR:\n return 'status_warning';\n case testStatus.SKIPPED:\n return 'status_skipped';\n case testStatus.UNKNOWN:\n default:\n return 'status_notfound';\n }\n}\nexport const formattedTime = (seconds = 0) => {\n if (seconds < 1) {\n return sprintf(__('%{milliseconds}ms'), {\n milliseconds: (seconds * 1000).toFixed(2),\n });\n }\n if (seconds < 60) {\n return sprintf(__('%{seconds}s'), {\n seconds: (seconds % 60).toFixed(2),\n });\n }\n\n const hoursAndMinutes = stringifyTime(parseSeconds(seconds));\n const remainingSeconds =\n seconds % 60 >= 1\n ? sprintf(__('%{seconds}s'), {\n seconds: Math.floor(seconds % 60),\n })\n : '';\n return `${hoursAndMinutes} ${remainingSeconds}`.trim();\n};\nexport const addIconStatus = (testCase) => ({\n ...testCase,\n icon: iconForTestStatus(testCase.status),\n formattedTime: formattedTime(testCase.execution_time),\n});\n","import { formatNumber, sprintf, __ } from '~/locale';\nimport { BYTES_IN_KIB, THOUSAND, MILLION } from './constants';\n\n/**\n * Utility function that calculates KiB of the given bytes.\n *\n * @param {Number} number bytes\n * @return {Number} KiB\n */\nexport function bytesToKiB(number) {\n return number / BYTES_IN_KIB;\n}\n\n/**\n * Utility function that calculates MiB of the given bytes.\n *\n * @param {Number} number bytes\n * @return {Number} MiB\n */\nexport function bytesToMiB(number) {\n return number / (BYTES_IN_KIB * BYTES_IN_KIB);\n}\n\n/**\n * Utility function that calculates GiB of the given bytes.\n * @param {Number} number\n * @returns {Number}\n */\nexport function bytesToGiB(number) {\n return number / (BYTES_IN_KIB * BYTES_IN_KIB * BYTES_IN_KIB);\n}\n\n/**\n * Formats the bytes in number into a more understandable\n * representation. Returns an array with the first value being the human size\n * and the second value being the label (e.g., [1.5, 'KiB']).\n *\n * @param {number} size\n * @param {number} [digits=2] - The number of digits to appear after the decimal point\n * @param {string} locale\n * @returns {string[]}\n */\nexport function numberToHumanSizeSplit({ size, digits = 2, locale } = {}) {\n const abs = Math.abs(size);\n const digitsOptions = { minimumFractionDigits: digits, maximumFractionDigits: digits };\n const formatNumberWithLocaleAndDigits = (n) => formatNumber(n, digitsOptions, locale);\n\n if (abs < BYTES_IN_KIB) {\n return [size.toString(), __('B')];\n }\n if (abs < BYTES_IN_KIB ** 2) {\n return [formatNumberWithLocaleAndDigits(bytesToKiB(size)), __('KiB')];\n }\n if (abs < BYTES_IN_KIB ** 3) {\n return [formatNumberWithLocaleAndDigits(bytesToMiB(size)), __('MiB')];\n }\n return [formatNumberWithLocaleAndDigits(bytesToGiB(size)), __('GiB')];\n}\n\n/**\n * Port of rails number_to_human_size\n * Formats the bytes in number into a more understandable\n * representation (e.g., giving it 1536 yields 1.5 KiB).\n *\n * @param {number} size\n * @param {number} [digits=2] - The number of digits to appear after the decimal point\n * @param {string} locale\n * @returns {string}\n */\nexport function numberToHumanSize(size, digits = 2, locale) {\n const [humanSize, label] = numberToHumanSizeSplit({ size, digits, locale });\n\n switch (label) {\n case __('B'):\n return sprintf(__('%{size} B'), { size: humanSize });\n case __('KiB'):\n return sprintf(__('%{size} KiB'), { size: humanSize });\n case __('MiB'):\n return sprintf(__('%{size} MiB'), { size: humanSize });\n case __('GiB'):\n return sprintf(__('%{size} GiB'), { size: humanSize });\n default:\n return '';\n }\n}\n\n/**\n * Converts a number to kilos or megas.\n *\n * For example:\n * - 123 becomes 123\n * - 123456 becomes 123.4k\n * - 123456789 becomes 123.4m\n *\n * @param number Number to format\n * @param digits The number of digits to appear after the decimal point\n * @param uppercase Whether to use uppercase suffix (K, M)\n * @return {string} Formatted number\n */\nexport function numberToMetricPrefix(number, uppercase = false) {\n if (number < THOUSAND) {\n return number.toString();\n }\n const digits = 1;\n if (number < MILLION) {\n return `${Number((number / THOUSAND).toFixed(digits))}${uppercase ? 'K' : 'k'}`;\n }\n return `${Number((number / MILLION).toFixed(digits))}${uppercase ? 'M' : 'm'}`;\n}\n/**\n * A simple method that returns the value of a + b\n * It seems unessesary, but when combined with a reducer it\n * adds up all the values in an array.\n *\n * e.g. `[1, 2, 3, 4, 5].reduce(sum) // => 15`\n *\n * @param {Float} a\n * @param {Float} b\n * @example\n * // return 15\n * [1, 2, 3, 4, 5].reduce(sum);\n *\n * // returns 6\n * Object.values([{a: 1, b: 2, c: 3].reduce(sum);\n * @returns {Float} The summed value\n */\nexport const sum = (a = 0, b = 0) => a + b;\n\n/**\n * Checks if the provided number is odd\n * @param {Int} number\n */\nexport const isOdd = (number = 0) => number % 2;\n\n/**\n * Computes the median for a given array.\n * @param {Array} arr An array of numbers\n * @returns {Number} The median of the given array\n */\nexport const median = (arr) => {\n const middle = Math.floor(arr.length / 2);\n const sorted = arr.sort((a, b) => a - b);\n return arr.length % 2 !== 0 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;\n};\n\n/**\n * Computes the change from one value to the other as a percentage.\n * @param {Number} firstY\n * @param {Number} lastY\n * @returns {Number}\n */\nexport const changeInPercent = (firstY, lastY) => {\n if (firstY === lastY) {\n return 0;\n }\n\n return Math.round(((lastY - firstY) / Math.abs(firstY)) * 100);\n};\n\n/**\n * Computes and formats the change from one value to the other as a percentage.\n * Prepends the computed percentage with either \"+\" or \"-\" to indicate an in- or decrease and\n * returns a given string if the result is not finite (for example, if the first value is \"0\").\n * @param firstY\n * @param lastY\n * @param nonFiniteResult\n * @returns {String}\n */\nexport const formattedChangeInPercent = (firstY, lastY, { nonFiniteResult = '-' } = {}) => {\n const change = changeInPercent(firstY, lastY);\n\n if (!Number.isFinite(change)) {\n return nonFiniteResult;\n }\n\n return `${change >= 0 ? '+' : ''}${change}%`;\n};\n\n/**\n * Checks whether a value is numerical in nature by converting it using parseInt\n *\n * Example outcomes:\n * - isNumeric(100) = true\n * - isNumeric('100') = true\n * - isNumeric(1.0) = true\n * - isNumeric('1.0') = true\n * - isNumeric('abc100') = false\n * - isNumeric('abc') = false\n * - isNumeric(true) = false\n * - isNumeric(undefined) = false\n * - isNumeric(null) = false\n *\n * @param value\n * @returns {boolean}\n */\nexport const isNumeric = (value) => {\n return !Number.isNaN(parseInt(value, 10));\n};\n\nconst numberRegex = /^[0-9]+$/;\n\n/**\n * Checks whether the value is a positive number or 0, or a string with equivalent value\n *\n * @param value\n * @return {boolean}\n */\nexport const isPositiveInteger = (value) => numberRegex.test(value);\n\n/**\n * Splits a number into an integer and decimal component\n * returns an object with the integer and decimal values extracted\n *\n * @param value\n * @return {Object}\n */\nexport const splitDecimalNumber = (value) => {\n if (isNumeric(value)) {\n const parts = String(value).split('.');\n if (value === 0) return { integer: '0', decimal: '0' };\n\n if (parts.length) {\n return parts.length > 1\n ? { integer: parts[0], decimal: parts[1] }\n : { integer: parts[0], decimal: null };\n }\n }\n return { integer: null, decimal: null };\n};\n\n/**\n * Calculates the number of digits after the decimal place\n *\n * @param num - any numeric value\n * @return number of digits after the decimal (if any)\n */\nexport const countFloatingPointDigits = (num = null) => {\n if (!num || !isNumeric(num)) return 0;\n\n const { decimal } = splitDecimalNumber(num);\n return String(decimal).length;\n};\n","import mod from \"-!../../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./pipeline_tabs.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./pipeline_tabs.vue?vue&type=script&lang=js\"","<script>\nimport { GlBadge, GlTabs, GlTab } from '@gitlab/ui';\nimport { TRACKING_CATEGORIES } from '~/ci/constants';\nimport { __ } from '~/locale';\nimport Tracking from '~/tracking';\nimport { isNumeric } from '~/lib/utils/number_utils';\nimport featureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';\nimport LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';\nimport {\n failedJobsTabName,\n jobsTabName,\n pipelineTabName,\n testReportTabName,\n manualVariablesTabName,\n} from '../constants';\n\nexport default {\n i18n: {\n tabs: {\n failedJobsTitle: __('Failed Jobs'),\n jobsTitle: __('Jobs'),\n pipelineTitle: __('Pipeline'),\n testsTitle: __('Tests'),\n manualVariables: __('Manual Variables'),\n },\n },\n tabNames: {\n pipeline: pipelineTabName,\n jobs: jobsTabName,\n failures: failedJobsTabName,\n tests: testReportTabName,\n manualVariables: manualVariablesTabName,\n },\n components: {\n GlBadge,\n GlTab,\n GlTabs,\n LocalStorageSync,\n },\n mixins: [Tracking.mixin(), featureFlagMixin()],\n inject: [\n 'defaultTabValue',\n 'failedJobsCount',\n 'totalJobCount',\n 'testsCount',\n 'manualVariablesCount',\n ],\n data() {\n return {\n activeTab: this.defaultTabValue,\n isDismissedNewTab: false,\n };\n },\n computed: {\n showFailedJobsTab() {\n return this.failedJobsCount > 0;\n },\n manualVariablesEnabled() {\n return (\n this.glFeatures.ciShowManualVariablesInPipeline && isNumeric(this.manualVariablesCount)\n );\n },\n },\n watch: {\n $route(to) {\n this.activeTab = to.name;\n },\n },\n methods: {\n isActive(tabName) {\n return tabName === this.activeTab;\n },\n navigateTo(tabName) {\n if (this.isActive(tabName)) return;\n\n this.$router.push({ name: tabName });\n },\n failedJobsTabClick() {\n this.track('click_tab', { label: TRACKING_CATEGORIES.failed });\n\n this.navigateTo(this.$options.tabNames.failures);\n },\n testsTabClick() {\n this.track('click_tab', { label: TRACKING_CATEGORIES.tests });\n\n this.navigateTo(this.$options.tabNames.tests);\n },\n manualVariablesTabClick() {\n this.track('click_tab', { label: TRACKING_CATEGORIES.manualVariables });\n this.isDismissedNewTab = true;\n\n this.navigateTo(this.$options.tabNames.manualVariables);\n },\n },\n MANUAL_VARIABLE_TAB_DISMISS_STORAGE_KEY: 'gl-ci-pipeline-detail-manual-variables-tab-dismissed',\n};\n</script>\n\n<template>\n <gl-tabs>\n <gl-tab\n ref=\"pipelineTab\"\n :title=\"$options.i18n.tabs.pipelineTitle\"\n :active=\"isActive($options.tabNames.pipeline)\"\n data-testid=\"pipeline-tab\"\n lazy\n @click=\"navigateTo($options.tabNames.pipeline)\"\n >\n <router-view />\n </gl-tab>\n <gl-tab\n :active=\"isActive($options.tabNames.jobs)\"\n data-testid=\"jobs-tab\"\n lazy\n @click=\"navigateTo($options.tabNames.jobs)\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.jobsTitle }}</span>\n <gl-badge data-testid=\"builds-counter\">{{ totalJobCount }}</gl-badge>\n </template>\n <router-view />\n </gl-tab>\n <gl-tab\n v-if=\"showFailedJobsTab\"\n :title=\"$options.i18n.tabs.failedJobsTitle\"\n :active=\"isActive($options.tabNames.failures)\"\n data-testid=\"failed-jobs-tab\"\n lazy\n @click=\"failedJobsTabClick\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.failedJobsTitle }}</span>\n <gl-badge data-testid=\"failed-builds-counter\">{{ failedJobsCount }}</gl-badge>\n </template>\n <router-view />\n </gl-tab>\n <gl-tab\n :active=\"isActive($options.tabNames.tests)\"\n data-testid=\"tests-tab\"\n lazy\n @click=\"testsTabClick\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.testsTitle }}</span>\n <gl-badge data-testid=\"tests-counter\">{{ testsCount }}</gl-badge>\n </template>\n <router-view />\n </gl-tab>\n <local-storage-sync\n v-if=\"manualVariablesEnabled\"\n v-model=\"isDismissedNewTab\"\n :storage-key=\"$options.MANUAL_VARIABLE_TAB_DISMISS_STORAGE_KEY\"\n >\n <gl-tab\n :active=\"isActive($options.tabNames.manualVariables)\"\n data-testid=\"manual-variables-tab\"\n lazy\n @click=\"manualVariablesTabClick\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.manualVariables }}</span>\n <gl-badge data-testid=\"manual-variables-counter\">{{ manualVariablesCount }}</gl-badge>\n <gl-badge\n v-if=\"!isDismissedNewTab\"\n data-testid=\"manual-variables-new-badge\"\n class=\"gl-ml-2\"\n variant=\"info\"\n >{{ __('new') }}</gl-badge\n >\n </template>\n <router-view />\n </gl-tab>\n </local-storage-sync>\n <slot></slot>\n </gl-tabs>\n</template>\n","import { render, staticRenderFns } from \"./pipeline_tabs.vue?vue&type=template&id=7c75bb55\"\nimport script from \"./pipeline_tabs.vue?vue&type=script&lang=js\"\nexport * from \"./pipeline_tabs.vue?vue&type=script&lang=js\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('gl-tabs',[_c('gl-tab',{ref:\"pipelineTab\",attrs:{\"title\":_vm.$options.i18n.tabs.pipelineTitle,\"active\":_vm.isActive(_vm.$options.tabNames.pipeline),\"data-testid\":\"pipeline-tab\",\"lazy\":\"\"},on:{\"click\":function($event){return _vm.navigateTo(_vm.$options.tabNames.pipeline)}}},[_c('router-view')],1),_vm._v(\" \"),_c('gl-tab',{attrs:{\"active\":_vm.isActive(_vm.$options.tabNames.jobs),\"data-testid\":\"jobs-tab\",\"lazy\":\"\"},on:{\"click\":function($event){return _vm.navigateTo(_vm.$options.tabNames.jobs)}},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.jobsTitle))]),_vm._v(\" \"),_c('gl-badge',{attrs:{\"data-testid\":\"builds-counter\"}},[_vm._v(_vm._s(_vm.totalJobCount))])]},proxy:true}])},[_vm._v(\" \"),_c('router-view')],1),_vm._v(\" \"),(_vm.showFailedJobsTab)?_c('gl-tab',{attrs:{\"title\":_vm.$options.i18n.tabs.failedJobsTitle,\"active\":_vm.isActive(_vm.$options.tabNames.failures),\"data-testid\":\"failed-jobs-tab\",\"lazy\":\"\"},on:{\"click\":_vm.failedJobsTabClick},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.failedJobsTitle))]),_vm._v(\" \"),_c('gl-badge',{attrs:{\"data-testid\":\"failed-builds-counter\"}},[_vm._v(_vm._s(_vm.failedJobsCount))])]},proxy:true}],null,false,90143673)},[_vm._v(\" \"),_c('router-view')],1):_vm._e(),_vm._v(\" \"),_c('gl-tab',{attrs:{\"active\":_vm.isActive(_vm.$options.tabNames.tests),\"data-testid\":\"tests-tab\",\"lazy\":\"\"},on:{\"click\":_vm.testsTabClick},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.testsTitle))]),_vm._v(\" \"),_c('gl-badge',{attrs:{\"data-testid\":\"tests-counter\"}},[_vm._v(_vm._s(_vm.testsCount))])]},proxy:true}])},[_vm._v(\" \"),_c('router-view')],1),_vm._v(\" \"),(_vm.manualVariablesEnabled)?_c('local-storage-sync',{attrs:{\"storage-key\":_vm.$options.MANUAL_VARIABLE_TAB_DISMISS_STORAGE_KEY},model:{value:(_vm.isDismissedNewTab),callback:function ($$v) {_vm.isDismissedNewTab=$$v},expression:\"isDismissedNewTab\"}},[_c('gl-tab',{attrs:{\"active\":_vm.isActive(_vm.$options.tabNames.manualVariables),\"data-testid\":\"manual-variables-tab\",\"lazy\":\"\"},on:{\"click\":_vm.manualVariablesTabClick},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.manualVariables))]),_vm._v(\" \"),_c('gl-badge',{attrs:{\"data-testid\":\"manual-variables-counter\"}},[_vm._v(_vm._s(_vm.manualVariablesCount))]),_vm._v(\" \"),(!_vm.isDismissedNewTab)?_c('gl-badge',{staticClass:\"gl-ml-2\",attrs:{\"data-testid\":\"manual-variables-new-badge\",\"variant\":\"info\"}},[_vm._v(_vm._s(_vm.__('new')))]):_vm._e()]},proxy:true}],null,false,3954460358)},[_vm._v(\" \"),_c('router-view')],1)],1):_vm._e(),_vm._v(\" \"),_vm._t(\"default\")],2)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./pipeline_tabs.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./pipeline_tabs.vue?vue&type=script&lang=js\"","<script>\nimport { GlTab, GlBadge } from '@gitlab/ui';\nimport Api from '~/api';\nimport BasePipelineTabs from '~/ci/pipeline_details/tabs/pipeline_tabs.vue';\nimport {\n codeQualityTabName,\n licensesTabName,\n securityTabName,\n} from '~/ci/pipeline_details/constants';\nimport { __ } from '~/locale';\nimport { SERVICE_PING_PIPELINE_SECURITY_VISIT } from '~/tracking/constants';\n\nexport default {\n i18n: {\n tabs: {\n securityTitle: __('Security'),\n codeQualityTitle: __('Code Quality'),\n licensesTitle: __('Licenses'),\n },\n },\n tabNames: {\n security: securityTabName,\n licenses: licensesTabName,\n codeQuality: codeQualityTabName,\n },\n components: {\n BasePipelineTabs,\n GlTab,\n GlBadge,\n },\n inject: [\n 'canGenerateCodequalityReports',\n 'canManageLicenses',\n 'codequalityReportDownloadPath',\n 'defaultTabValue',\n 'exposeSecurityDashboard',\n 'exposeLicenseScanningData',\n 'isFullCodequalityReportAvailable',\n 'licensesApiPath',\n 'licenseManagementApiUrl',\n 'licenseScanCount',\n 'pipelineIid',\n 'securityPoliciesPath',\n ],\n props: {\n sbomReportsErrors: {\n type: Array,\n required: true,\n },\n },\n data() {\n return {\n activeTab: this.defaultTabValue,\n codeQualityCount: undefined,\n codeQualityCountFetched: false,\n licenseCount: this.licenseScanCount,\n };\n },\n computed: {\n showCodeQualityTab() {\n return Boolean(\n this.isFullCodequalityReportAvailable &&\n (this.codequalityReportDownloadPath || this.canGenerateCodequalityReports),\n );\n },\n showLicenseTab() {\n return Boolean(this.exposeLicenseScanningData);\n },\n showSecurityTab() {\n return Boolean(this.exposeSecurityDashboard);\n },\n showLicenseCount() {\n return Boolean(this.licenseCount !== undefined);\n },\n },\n watch: {\n $route(to) {\n this.activeTab = to.name;\n },\n },\n methods: {\n isActive(tabName) {\n return tabName === this.activeTab;\n },\n navigateTo(tabName) {\n if (this.isActive(tabName)) return;\n\n this.$router.push({ name: tabName });\n },\n navigateToSecurity() {\n this.navigateTo(this.$options.tabNames.security);\n Api.trackRedisHllUserEvent(SERVICE_PING_PIPELINE_SECURITY_VISIT);\n },\n updateCodeQualityCount(count) {\n this.codeQualityCountFetched = true;\n this.codeQualityCount = count;\n },\n updateLicenseCount(count) {\n this.licenseCount = count;\n },\n },\n};\n</script>\n\n<template>\n <base-pipeline-tabs>\n <gl-tab\n v-if=\"showSecurityTab\"\n :title=\"$options.i18n.tabs.securityTitle\"\n :active=\"isActive($options.tabNames.security)\"\n data-testid=\"security-tab\"\n lazy\n @click=\"navigateToSecurity\"\n >\n <router-view :sbom-reports-errors=\"sbomReportsErrors\" />\n </gl-tab>\n <gl-tab\n v-if=\"showLicenseTab\"\n :title=\"$options.i18n.tabs.licensesTitle\"\n :active=\"isActive($options.tabNames.licenses)\"\n data-testid=\"license-tab\"\n lazy\n @click=\"navigateTo($options.tabNames.licenses)\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.licensesTitle }}</span>\n <gl-badge v-if=\"showLicenseCount\" data-testid=\"license-counter\">{{\n licenseCount\n }}</gl-badge>\n </template>\n\n <router-view\n ref=\"router-view-licenses\"\n :api-url=\"licenseManagementApiUrl\"\n :licenses-api-path=\"licensesApiPath\"\n :security-policies-path=\"securityPoliciesPath\"\n :can-manage-licenses=\"canManageLicenses\"\n :always-open=\"true\"\n report-section-class=\"split-report-section\"\n :sbom-reports-errors=\"sbomReportsErrors\"\n @updateBadgeCount=\"updateLicenseCount\"\n />\n </gl-tab>\n <gl-tab\n v-if=\"showCodeQualityTab\"\n :title=\"$options.i18n.tabs.codeQualityTitle\"\n :active=\"isActive($options.tabNames.codeQuality)\"\n data-testid=\"code-quality-tab\"\n data-track-action=\"click_button\"\n data-track-label=\"get_codequality_report\"\n lazy\n @click=\"navigateTo($options.tabNames.codeQuality)\"\n >\n <template #title>\n <span class=\"gl-mr-2\">{{ $options.i18n.tabs.codeQualityTitle }}</span>\n <gl-badge v-if=\"codeQualityCountFetched\" data-testid=\"codequality-counter\">{{\n codeQualityCount\n }}</gl-badge>\n </template>\n\n <router-view ref=\"router-view-codequality\" @updateBadgeCount=\"updateCodeQualityCount\" />\n </gl-tab>\n </base-pipeline-tabs>\n</template>\n","import { render, staticRenderFns } from \"./pipeline_tabs.vue?vue&type=template&id=ecc624ea\"\nimport script from \"./pipeline_tabs.vue?vue&type=script&lang=js\"\nexport * from \"./pipeline_tabs.vue?vue&type=script&lang=js\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('base-pipeline-tabs',[(_vm.showSecurityTab)?_c('gl-tab',{attrs:{\"title\":_vm.$options.i18n.tabs.securityTitle,\"active\":_vm.isActive(_vm.$options.tabNames.security),\"data-testid\":\"security-tab\",\"lazy\":\"\"},on:{\"click\":_vm.navigateToSecurity}},[_c('router-view',{attrs:{\"sbom-reports-errors\":_vm.sbomReportsErrors}})],1):_vm._e(),_vm._v(\" \"),(_vm.showLicenseTab)?_c('gl-tab',{attrs:{\"title\":_vm.$options.i18n.tabs.licensesTitle,\"active\":_vm.isActive(_vm.$options.tabNames.licenses),\"data-testid\":\"license-tab\",\"lazy\":\"\"},on:{\"click\":function($event){return _vm.navigateTo(_vm.$options.tabNames.licenses)}},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.licensesTitle))]),_vm._v(\" \"),(_vm.showLicenseCount)?_c('gl-badge',{attrs:{\"data-testid\":\"license-counter\"}},[_vm._v(_vm._s(_vm.licenseCount))]):_vm._e()]},proxy:true}],null,false,3115493630)},[_vm._v(\" \"),_c('router-view',{ref:\"router-view-licenses\",attrs:{\"api-url\":_vm.licenseManagementApiUrl,\"licenses-api-path\":_vm.licensesApiPath,\"security-policies-path\":_vm.securityPoliciesPath,\"can-manage-licenses\":_vm.canManageLicenses,\"always-open\":true,\"report-section-class\":\"split-report-section\",\"sbom-reports-errors\":_vm.sbomReportsErrors},on:{\"updateBadgeCount\":_vm.updateLicenseCount}})],1):_vm._e(),_vm._v(\" \"),(_vm.showCodeQualityTab)?_c('gl-tab',{attrs:{\"title\":_vm.$options.i18n.tabs.codeQualityTitle,\"active\":_vm.isActive(_vm.$options.tabNames.codeQuality),\"data-testid\":\"code-quality-tab\",\"data-track-action\":\"click_button\",\"data-track-label\":\"get_codequality_report\",\"lazy\":\"\"},on:{\"click\":function($event){return _vm.navigateTo(_vm.$options.tabNames.codeQuality)}},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('span',{staticClass:\"gl-mr-2\"},[_vm._v(_vm._s(_vm.$options.i18n.tabs.codeQualityTitle))]),_vm._v(\" \"),(_vm.codeQualityCountFetched)?_c('gl-badge',{attrs:{\"data-testid\":\"codequality-counter\"}},[_vm._v(_vm._s(_vm.codeQualityCount))]):_vm._e()]},proxy:true}],null,false,993111475)},[_vm._v(\" \"),_c('router-view',{ref:\"router-view-codequality\",on:{\"updateBadgeCount\":_vm.updateCodeQualityCount}})],1):_vm._e()],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","export const SET_PAGE = 'SET_PAGE';\nexport const SET_SELECTED_SUITE_INDEX = 'SET_SELECTED_SUITE_INDEX';\nexport const SET_SUMMARY = 'SET_SUMMARY';\nexport const SET_SUITE = 'SET_SUITE';\nexport const SET_SUITE_ERROR = 'SET_SUITE_ERROR';\nexport const TOGGLE_LOADING = 'TOGGLE_LOADING';\n","import { createAlert } from '~/alert';\nimport axios from '~/lib/utils/axios_utils';\nimport { s__ } from '~/locale';\nimport * as types from './mutation_types';\n\nexport const fetchSummary = ({ state, commit, dispatch }) => {\n dispatch('toggleLoading');\n\n return axios\n .get(state.summaryEndpoint)\n .then(({ data }) => {\n commit(types.SET_SUMMARY, data);\n })\n .catch(() => {\n createAlert({\n message: s__('TestReports|There was an error fetching the summary.'),\n });\n })\n .finally(() => {\n dispatch('toggleLoading');\n });\n};\n\nexport const fetchTestSuite = ({ state, commit, dispatch }, index) => {\n const { hasFullSuite } = state.testReports?.test_suites?.[index] || {};\n // We don't need to fetch the suite if we have the information already\n if (hasFullSuite) {\n return Promise.resolve();\n }\n\n dispatch('toggleLoading');\n\n const { build_ids = [] } = state.testReports?.test_suites?.[index] || {};\n // Replacing `/:suite_name.json` with the name of the suite. Including the extra characters\n // to ensure that we replace exactly the template part of the URL string\n\n return axios\n .get(state.suiteEndpoint, { params: { build_ids } })\n .then(({ data }) => commit(types.SET_SUITE, { suite: data, index }))\n .catch((error) => commit(types.SET_SUITE_ERROR, error))\n .finally(() => {\n dispatch('toggleLoading');\n });\n};\n\nexport const setPage = ({ commit }, page) => commit(types.SET_PAGE, page);\nexport const setSelectedSuiteIndex = ({ commit }, data) =>\n commit(types.SET_SELECTED_SUITE_INDEX, data);\nexport const removeSelectedSuiteIndex = ({ commit }) =>\n commit(types.SET_SELECTED_SUITE_INDEX, null);\nexport const toggleLoading = ({ commit }) => commit(types.TOGGLE_LOADING);\n","export const ARTIFACTS_EXPIRED_ERROR_MESSAGE = 'Test report artifacts not found';\n","import { addIconStatus, formatFilePath, formattedTime } from './utils';\nimport { ARTIFACTS_EXPIRED_ERROR_MESSAGE } from './constants';\n\nexport const getTestSuites = (state) => {\n const { test_suites: testSuites = [] } = state.testReports;\n\n return testSuites.map((suite) => ({\n ...suite,\n formattedTime: formattedTime(suite.total_time),\n }));\n};\n\nexport const getSelectedSuite = (state) =>\n state.testReports?.test_suites?.[state.selectedSuiteIndex] || {};\n\nexport const getSuiteTests = (state) => {\n const { test_cases: testCases = [] } = getSelectedSuite(state);\n const { page, perPage } = state.pageInfo;\n const start = (page - 1) * perPage;\n\n return testCases\n .map((testCase) => ({\n ...testCase,\n classname: testCase.classname || '',\n name: testCase.name || '',\n filePath: testCase.file ? `${state.blobPath}/${formatFilePath(testCase.file)}` : null,\n }))\n .map(addIconStatus)\n .slice(start, start + perPage);\n};\n\nexport const getSuiteTestCount = (state) => getSelectedSuite(state)?.test_cases?.length || 0;\n\nexport const getSuiteArtifactsExpired = (state) =>\n state.errorMessage === ARTIFACTS_EXPIRED_ERROR_MESSAGE;\n","import { createAlert } from '~/alert';\nimport { s__ } from '~/locale';\nimport * as types from './mutation_types';\n\nexport default {\n [types.SET_PAGE](state, page) {\n Object.assign(state, {\n pageInfo: Object.assign(state.pageInfo, {\n page,\n }),\n });\n },\n\n [types.SET_SUITE](state, { suite = {}, index = null }) {\n state.testReports.test_suites[index] = { ...suite, hasFullSuite: true };\n },\n\n [types.SET_SUITE_ERROR](state, error) {\n const errorMessage = error.response?.data?.errors;\n\n if (errorMessage) {\n state.errorMessage = errorMessage;\n } else {\n createAlert({\n message: s__('TestReports|There was an error fetching the test suite.'),\n });\n }\n },\n\n [types.SET_SELECTED_SUITE_INDEX](state, selectedSuiteIndex) {\n Object.assign(state, { selectedSuiteIndex });\n },\n\n [types.SET_SUMMARY](state, testReports) {\n const { total } = testReports;\n state.testReports = {\n ...testReports,\n\n /*\n TLDR; this is a temporary mapping that will be updated once\n test suites have the new data schema\n\n The backend is in the middle of updating the data schema\n to have a `total` object containing the total data values.\n The test suites don't have the new schema, but the summary\n does. Currently the `test_summary.vue` component takes both\n the summary and a test suite depending on what is being viewed.\n This is a temporary change to map the new schema to the old until\n we can update the schema for the test suites also.\n Since test suites is an array, it is easier to just map the summary\n to the old schema instead of mapping every test suite to the new.\n */\n\n total_time: total.time,\n total_count: total.count,\n success_count: total.success,\n failed_count: total.failed,\n skipped_count: total.skipped,\n error_count: total.error,\n };\n },\n\n [types.TOGGLE_LOADING](state) {\n Object.assign(state, { isLoading: !state.isLoading });\n },\n};\n","export default ({ blobPath = '', summaryEndpoint = '', suiteEndpoint = '' }) => ({\n blobPath,\n summaryEndpoint,\n suiteEndpoint,\n testReports: {},\n selectedSuiteIndex: null,\n isLoading: false,\n errorMessage: null,\n pageInfo: {\n page: 1,\n perPage: 20,\n },\n});\n","import Vue from 'vue';\nimport VueRouter from 'vue-router';\n// eslint-disable-next-line no-restricted-imports\nimport Vuex from 'vuex';\nimport VueApollo from 'vue-apollo';\nimport { GlToast } from '@gitlab/ui';\nimport PipelineTabs from 'ee_else_ce/ci/pipeline_details/tabs/pipeline_tabs.vue';\nimport { parseBoolean } from '~/lib/utils/common_utils';\nimport createTestReportsStore from './stores/test_reports';\nimport { getPipelineDefaultTab } from './utils';\n\nVue.use(GlToast);\nVue.use(VueApollo);\nVue.use(VueRouter);\nVue.use(Vuex);\n\nexport const createAppOptions = (selector, apolloProvider, router) => {\n const el = document.querySelector(selector);\n\n if (!el) return null;\n\n const { dataset } = el;\n const {\n canGenerateCodequalityReports,\n codequalityReportDownloadPath,\n codequalityBlobPath,\n codequalityProjectPath,\n downloadablePathForReportType,\n exposeSecurityDashboard,\n exposeLicenseScanningData,\n failedJobsCount,\n projectPath,\n graphqlResourceEtag,\n pipelineIid,\n pipelineProjectPath,\n totalJobCount,\n licenseManagementApiUrl,\n licenseScanCount,\n licensesApiPath,\n canManageLicenses,\n summaryEndpoint,\n suiteEndpoint,\n blobPath,\n hasTestReport,\n emptyStateImagePath,\n artifactsExpiredImagePath,\n isFullCodequalityReportAvailable,\n securityPoliciesPath,\n testsCount,\n manualVariablesCount,\n canReadVariables,\n } = dataset;\n\n const defaultTabValue = getPipelineDefaultTab(window.location.href);\n\n return {\n el,\n components: {\n PipelineTabs,\n },\n apolloProvider,\n store: new Vuex.Store({\n modules: {\n testReports: createTestReportsStore({\n blobPath,\n summaryEndpoint,\n suiteEndpoint,\n }),\n },\n }),\n router,\n provide: {\n canGenerateCodequalityReports: parseBoolean(canGenerateCodequalityReports),\n codequalityReportDownloadPath,\n codequalityBlobPath,\n codequalityProjectPath,\n isFullCodequalityReportAvailable: parseBoolean(isFullCodequalityReportAvailable),\n projectPath,\n defaultTabValue,\n downloadablePathForReportType,\n exposeSecurityDashboard: parseBoolean(exposeSecurityDashboard),\n exposeLicenseScanningData: parseBoolean(exposeLicenseScanningData),\n failedJobsCount,\n graphqlResourceEtag,\n pipelineIid,\n pipelineProjectPath,\n totalJobCount,\n licenseManagementApiUrl,\n licenseScanCount,\n licensesApiPath,\n canManageLicenses: parseBoolean(canManageLicenses),\n summaryEndpoint,\n suiteEndpoint,\n blobPath,\n hasTestReport,\n emptyStateImagePath,\n artifactsExpiredImagePath,\n securityPoliciesPath,\n testsCount,\n manualVariablesCount: Number.parseInt(manualVariablesCount, 10),\n canReadVariables: parseBoolean(canReadVariables),\n },\n render(createElement, props = {}) {\n return createElement(PipelineTabs, { props });\n },\n };\n};\n\nexport const createPipelineTabs = (options) => {\n if (!options) return;\n\n // eslint-disable-next-line no-new\n new Vue(options);\n};\n","import * as actions from './actions';\nimport * as getters from './getters';\nimport mutations from './mutations';\nimport state from './state';\n\nexport default (initialState) => {\n return {\n namespaced: true,\n actions,\n getters,\n mutations,\n state: state(initialState),\n };\n};\n"],"sourceRoot":""}