This instance will be upgraded to Heptapod 0.31.0 (final) on 2022-05-24 at 14:00 UTC+2 (a few minutes of down time)

Commit 30477a73 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 39c33be74dcb
<script>
import { createNamespacedHelpers, mapState, mapActions } from 'vuex';
import { createNamespacedHelpers, mapState, mapActions, mapGetters } from 'vuex';
import { escape as esc } from 'lodash';
import { GlFormInput, GlFormCheckbox } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
......@@ -61,6 +61,7 @@ export default {
'gitlabManagedCluster',
'isCreatingCluster',
]),
...mapGetters(['subnetValid']),
...mapRolesState({
roles: 'items',
isLoadingRoles: 'isLoadingItems',
......@@ -119,7 +120,7 @@ export default {
!this.selectedRegion ||
!this.selectedKeyPair ||
!this.selectedVpc ||
!this.selectedSubnet ||
!this.subnetValid ||
!this.selectedRole ||
!this.selectedSecurityGroup ||
!this.selectedInstanceType ||
......@@ -127,6 +128,9 @@ export default {
this.isCreatingCluster
);
},
displaySubnetError() {
return Boolean(this.loadingSubnetsError) || this.selectedSubnet?.length === 1;
},
createClusterButtonLabel() {
return this.isCreatingCluster
? s__('ClusterIntegration|Creating Kubernetes cluster')
......@@ -216,6 +220,13 @@ export default {
false,
);
},
subnetValidationErrorText() {
if (this.loadingSubnetsError) {
return s__('ClusterIntegration|Could not load subnets for the selected VPC');
}
return s__('ClusterIntegration|You should select at least two subnets');
},
securityGroupDropdownHelpText() {
return sprintf(
s__(
......@@ -289,14 +300,14 @@ export default {
this.setRegion({ region });
this.setVpc({ vpc: null });
this.setKeyPair({ keyPair: null });
this.setSubnet({ subnet: null });
this.setSubnet({ subnet: [] });
this.setSecurityGroup({ securityGroup: null });
this.fetchVpcs({ region });
this.fetchKeyPairs({ region });
},
setVpcAndFetchSubnets(vpc) {
this.setVpc({ vpc });
this.setSubnet({ subnet: null });
this.setSubnet({ subnet: [] });
this.setSecurityGroup({ securityGroup: null });
this.fetchSubnets({ vpc, region: this.selectedRegion });
this.fetchSecurityGroups({ vpc, region: this.selectedRegion });
......@@ -436,8 +447,8 @@ export default {
:placeholder="s__('ClusterIntergation|Select a subnet')"
:search-field-placeholder="s__('ClusterIntegration|Search subnets')"
:empty-text="s__('ClusterIntegration|No subnet found')"
:has-errors="Boolean(loadingSubnetsError)"
:error-message="s__('ClusterIntegration|Could not load subnets for the selected VPC')"
:has-errors="displaySubnetError"
:error-message="subnetValidationErrorText"
@input="setSubnet({ subnet: $event })"
/>
<p class="form-text text-muted" v-html="subnetDropdownHelpText"></p>
......
// eslint-disable-next-line import/prefer-default-export
export const subnetValid = ({ selectedSubnet }) =>
Array.isArray(selectedSubnet) && selectedSubnet.length >= 2;
......@@ -21,7 +21,7 @@ export default () => ({
selectedRole: '',
selectedKeyPair: '',
selectedVpc: '',
selectedSubnet: '',
selectedSubnet: [],
selectedSecurityGroup: '',
selectedInstanceType: 'm5.large',
nodeCount: '3',
......
......@@ -50,6 +50,11 @@ export default {
type: String,
required: true,
},
endpointCoverage: {
type: String,
required: false,
default: '',
},
projectPath: {
type: String,
required: true,
......@@ -169,6 +174,7 @@ export default {
endpoint: this.endpoint,
endpointMetadata: this.endpointMetadata,
endpointBatch: this.endpointBatch,
endpointCoverage: this.endpointCoverage,
projectPath: this.projectPath,
dismissEndpoint: this.dismissEndpoint,
showSuggestPopover: this.showSuggestPopover,
......@@ -218,6 +224,7 @@ export default {
'fetchDiffFiles',
'fetchDiffFilesMeta',
'fetchDiffFilesBatch',
'fetchCoverageFiles',
'startRenderDiffsQueue',
'assignDiscussionsToDiff',
'setHighlightedRow',
......@@ -292,6 +299,10 @@ export default {
});
}
if (this.endpointCoverage) {
this.fetchCoverageFiles();
}
if (!this.isNotesFetched) {
eventHub.$emit('fetchNotesData');
}
......
......@@ -54,7 +54,7 @@ export default {
colspan: {
type: Number,
required: false,
default: 3,
default: 4,
},
},
computed: {
......
......@@ -51,7 +51,7 @@ export default {
<template>
<tr v-if="shouldRender" :class="className" class="notes_holder">
<td class="notes-content" colspan="3">
<td class="notes-content" colspan="4">
<div class="content">
<diff-discussions
v-if="line.discussions.length"
......
<script>
import { mapActions, mapState } from 'vuex';
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui';
import DiffTableCell from './diff_table_cell.vue';
import {
MATCH_LINE_TYPE,
......@@ -15,11 +16,18 @@ export default {
components: {
DiffTableCell,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
fileHash: {
type: String,
required: true,
},
filePath: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
......@@ -40,6 +48,7 @@ export default {
};
},
computed: {
...mapGetters('diffs', ['fileLineCoverage']),
...mapState({
isHighlighted(state) {
return this.line.line_code !== null && this.line.line_code === state.diffs.highlightedRow;
......@@ -62,6 +71,9 @@ export default {
isMatchLine() {
return this.line.type === MATCH_LINE_TYPE;
},
coverageState() {
return this.fileLineCoverage(this.filePath, this.line.new_line);
},
},
created() {
this.newLineType = NEW_LINE_TYPE;
......@@ -113,6 +125,12 @@ export default {
:is-highlighted="isHighlighted"
class="diff-line-num new_line qa-new-diff-line"
/>
<td
v-gl-tooltip.hover
:title="coverageState.text"
:class="[line.type, coverageState.class, { hll: isHighlighted }]"
class="line-coverage"
></td>
<td
:class="[
line.type,
......@@ -120,7 +138,7 @@ export default {
hll: isHighlighted,
},
]"
class="line_content"
class="line_content with-coverage"
v-html="line.rich_text"
></td>
</tr>
......
......@@ -48,6 +48,7 @@ export default {
<colgroup>
<col style="width: 50px;" />
<col style="width: 50px;" />
<col style="width: 8px;" />
<col />
</colgroup>
<tbody>
......@@ -63,6 +64,7 @@ export default {
<inline-diff-table-row
:key="`${line.line_code || index}`"
:file-hash="diffFile.file_hash"
:file-path="diffFile.file_path"
:context-lines-path="diffFile.context_lines_path"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
......
......@@ -122,7 +122,7 @@ export default {
<template>
<tr v-if="shouldRender" :class="className" class="notes_holder">
<td class="notes-content parallel old" colspan="2">
<td class="notes-content parallel old" colspan="3">
<div v-if="shouldRenderDiscussionsOnLeft" class="content">
<diff-discussions
:discussions="line.left.discussions"
......@@ -147,7 +147,7 @@ export default {
</template>
</diff-discussion-reply>
</td>
<td class="notes-content parallel new" colspan="2">
<td class="notes-content parallel new" colspan="3">
<div v-if="shouldRenderDiscussionsOnRight" class="content">
<diff-discussions
:discussions="line.right.discussions"
......
......@@ -49,7 +49,7 @@ export default {
:line="line.left"
:is-top="isTop"
:is-bottom="isBottom"
:colspan="4"
:colspan="6"
/>
</template>
</tr>
......
<script>
import { mapActions, mapState } from 'vuex';
import { mapActions, mapGetters, mapState } from 'vuex';
import $ from 'jquery';
import { GlTooltipDirective } from '@gitlab/ui';
import DiffTableCell from './diff_table_cell.vue';
import {
MATCH_LINE_TYPE,
......@@ -18,11 +19,18 @@ export default {
components: {
DiffTableCell,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
fileHash: {
type: String,
required: true,
},
filePath: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
......@@ -44,6 +52,7 @@ export default {
};
},
computed: {
...mapGetters('diffs', ['fileLineCoverage']),
...mapState({
isHighlighted(state) {
const lineCode =
......@@ -82,6 +91,9 @@ export default {
isMatchLineRight() {
return this.line.right && this.line.right.type === MATCH_LINE_TYPE;
},
coverageState() {
return this.fileLineCoverage(this.filePath, this.line.right.new_line);
},
},
created() {
this.newLineType = NEW_LINE_TYPE;
......@@ -99,7 +111,7 @@ export default {
const allCellsInHoveringRow = Array.from(e.currentTarget.children);
const hoverIndex = allCellsInHoveringRow.indexOf(hoveringCell);
if (hoverIndex >= 2) {
if (hoverIndex >= 3) {
this.isRightHover = isHover;
} else {
this.isLeftHover = isHover;
......@@ -143,17 +155,19 @@ export default {
line-position="left"
class="diff-line-num old_line"
/>
<td :class="parallelViewLeftLineType" class="line-coverage left-side"></td>
<td
:id="line.left.line_code"
:class="parallelViewLeftLineType"
class="line_content parallel left-side"
class="line_content with-coverage parallel left-side"
@mousedown="handleParallelLineMouseDown"
v-html="line.left.rich_text"
></td>
</template>
<template v-else>
<td class="diff-line-num old_line empty-cell"></td>
<td class="line_content parallel left-side empty-cell"></td>
<td class="line-coverage left-side empty-cell"></td>
<td class="line_content with-coverage parallel left-side empty-cell"></td>
</template>
<template v-if="line.right && !isMatchLineRight">
<diff-table-cell
......@@ -169,6 +183,12 @@ export default {
line-position="right"
class="diff-line-num new_line"
/>
<td
v-gl-tooltip.hover
:title="coverageState.text"
:class="[line.right.type, coverageState.class, { hll: isHighlighted }]"
class="line-coverage right-side"
></td>
<td
:id="line.right.line_code"
:class="[
......@@ -177,14 +197,15 @@ export default {
hll: isHighlighted,
},
]"
class="line_content parallel right-side"
class="line_content with-coverage parallel right-side"
@mousedown="handleParallelLineMouseDown"
v-html="line.right.rich_text"
></td>
</template>
<template v-else>
<td class="diff-line-num old_line empty-cell"></td>
<td class="line_content parallel right-side empty-cell"></td>
<td class="line-coverage right-side empty-cell"></td>
<td class="line_content with-coverage parallel right-side empty-cell"></td>
</template>
</tr>
</template>
......@@ -47,8 +47,10 @@ export default {
>
<colgroup>
<col style="width: 50px;" />
<col style="width: 8px;" />
<col />
<col style="width: 50px;" />
<col style="width: 8px;" />
<col />
</colgroup>
<tbody>
......@@ -64,6 +66,7 @@ export default {
<parallel-diff-table-row
:key="line.line_code"
:file-hash="diffFile.file_hash"
:file-path="diffFile.file_path"
:context-lines-path="diffFile.context_lines_path"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
......
......@@ -69,6 +69,7 @@ export default function initDiffsApp(store) {
endpoint: dataset.endpoint,
endpointMetadata: dataset.endpointMetadata || '',
endpointBatch: dataset.endpointBatch || '',
endpointCoverage: dataset.endpointCoverage || '',
projectPath: dataset.projectPath,
helpPagePath: dataset.helpPagePath,
currentUser: JSON.parse(dataset.currentUserData) || {},
......@@ -104,6 +105,7 @@ export default function initDiffsApp(store) {
endpoint: this.endpoint,
endpointMetadata: this.endpointMetadata,
endpointBatch: this.endpointBatch,
endpointCoverage: this.endpointCoverage,
currentUser: this.currentUser,
projectPath: this.projectPath,
helpPagePath: this.helpPagePath,
......
import Vue from 'vue';
import Cookies from 'js-cookie';
import Poll from '~/lib/utils/poll';
import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import { __, s__ } from '~/locale';
import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils';
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
import TreeWorker from '../workers/tree_worker';
......@@ -43,6 +45,7 @@ export const setBaseConfig = ({ commit }, options) => {
endpoint,
endpointMetadata,
endpointBatch,
endpointCoverage,
projectPath,
dismissEndpoint,
showSuggestPopover,
......@@ -52,6 +55,7 @@ export const setBaseConfig = ({ commit }, options) => {
endpoint,
endpointMetadata,
endpointBatch,
endpointCoverage,
projectPath,
dismissEndpoint,
showSuggestPopover,
......@@ -170,6 +174,26 @@ export const fetchDiffFilesMeta = ({ commit, state }) => {
.catch(() => worker.terminate());
};
export const fetchCoverageFiles = ({ commit, state }) => {
const coveragePoll = new Poll({
resource: {
getCoverageReports: endpoint => axios.get(endpoint),
},
data: state.endpointCoverage,
method: 'getCoverageReports',
successCallback: ({ status, data }) => {
if (status === httpStatusCodes.OK) {
commit(types.SET_COVERAGE_DATA, data);
coveragePoll.stop();
}
},
errorCallback: () => createFlash(__('Something went wrong on our end. Please try again!')),
});
coveragePoll.makeRequest();
};
export const setHighlightedRow = ({ commit }, lineCode) => {
const fileHash = lineCode.split('_')[0];
commit(types.SET_HIGHLIGHTED_ROW, lineCode);
......
import { __, n__ } from '~/locale';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants';
export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE;
......@@ -98,6 +99,29 @@ export const allBlobs = (state, getters) =>
export const getCommentFormForDiffFile = state => fileHash =>
state.commentForms.find(form => form.fileHash === fileHash);
/**
* Returns the test coverage hits for a specific line of a given file
* @param {string} file
* @param {number} line
* @returns {number}
*/
export const fileLineCoverage = state => (file, line) => {
if (!state.coverageFiles.files) return {};
const fileCoverage = state.coverageFiles.files[file];
if (!fileCoverage) return {};
const lineCoverage = fileCoverage[String(line)];
if (lineCoverage === 0) {
return { text: __('No test coverage'), class: 'no-coverage' };
} else if (lineCoverage >= 0) {
return {
text: n__('Test coverage: %d hit', 'Test coverage: %d hits', lineCoverage),
class: 'coverage',
};
}
return {};
};
/**
* Returns index of a currently selected diff in diffFiles
* @returns {number}
......
......@@ -17,6 +17,7 @@ export default () => ({
commit: null,
startVersion: null,
diffFiles: [],
coverageFiles: {},
mergeRequestDiffs: [],
mergeRequestDiff: null,
diffViewType: viewTypeFromQueryString || viewTypeFromCookie || defaultViewType,
......
......@@ -5,6 +5,7 @@ export const SET_RETRIEVING_BATCHES = 'SET_RETRIEVING_BATCHES';
export const SET_DIFF_DATA = 'SET_DIFF_DATA';
export const SET_DIFF_DATA_BATCH = 'SET_DIFF_DATA_BATCH';
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
export const SET_COVERAGE_DATA = 'SET_COVERAGE_DATA';
export const SET_MERGE_REQUEST_DIFFS = 'SET_MERGE_REQUEST_DIFFS';
export const TOGGLE_LINE_HAS_FORM = 'TOGGLE_LINE_HAS_FORM';
export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES';
......
......@@ -16,6 +16,7 @@ export default {
endpoint,
endpointMetadata,
endpointBatch,
endpointCoverage,
projectPath,
dismissEndpoint,
showSuggestPopover,
......@@ -25,6 +26,7 @@ export default {
endpoint,
endpointMetadata,
endpointBatch,
endpointCoverage,
projectPath,
dismissEndpoint,
showSuggestPopover,
......@@ -69,6 +71,10 @@ export default {
});
},
[types.SET_COVERAGE_DATA](state, coverageFiles) {
Object.assign(state, { coverageFiles });
},
[types.RENDER_FILE](state, file) {
Object.assign(file, {
renderIt: true,
......
......@@ -29,3 +29,15 @@
color: $link;
}
}
@mixin line-coverage-border-color($coverage, $no-coverage) {
transition: border-left 0.1s ease-out;
&.coverage {
border-left: 3px solid $coverage;
}
&.no-coverage {
border-left: 3px solid $no-coverage;
}
}
......@@ -24,6 +24,8 @@ $dark-pre-hll-bg: #373b41;
$dark-hll-bg: #373b41;
$dark-over-bg: #9f9ab5;
$dark-expanded-bg: #3e3e3e;
$dark-coverage: #b5bd68;
$dark-no-coverage: #de935f;
$dark-c: #969896;
$dark-err: #c66;
$dark-k: #b294bb;
......@@ -124,12 +126,18 @@ $dark-il: #de935f;
}
td.diff-line-num.hll:not(.empty-cell),
td.line-coverage.hll:not(.empty-cell),
td.line_content.hll:not(.empty-cell) {
background-color: $dark-diff-not-empty-bg;
border-color: darken($dark-diff-not-empty-bg, 15%);
}
.line-coverage {
@include line-coverage-border-color($dark-coverage, $dark-no-coverage);
}
.diff-line-num.new,
.line-coverage.new,
.line_content.new {
@include diff-background($dark-new-bg, $dark-new-idiff, $dark-border);
......@@ -140,6 +148,7 @@ $dark-il: #de935f;
}
.diff-line-num.old,
.line-coverage.old,
.line_content.old {
@include diff-background($dark-old-bg, $dark-old-idiff, $dark-border);
......@@ -168,6 +177,7 @@ $dark-il: #de935f;
&:not(.diff-expanded) + .diff-expanded,
&.diff-expanded + .line_holder:not(.diff-expanded) {
> .diff-line-num,
> .line-coverage,
> .line_content {
border-top: 1px solid $black;
}
......@@ -175,6 +185,7 @@ $dark-il: #de935f;
&.diff-expanded {
> .diff-line-num,
> .line-coverage,
> .line_content {
background: $dark-expanded-bg;
border-color: $dark-expanded-bg;
......