Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
03c7356304
commit
33212c8ff1
|
|
@ -263,13 +263,13 @@ export default {
|
|||
commit(types.MOVE_ISSUE, { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId });
|
||||
|
||||
const { boardId } = state.endpoints;
|
||||
const [groupPath, project] = issuePath.split(/[/#]/);
|
||||
const [fullProjectPath] = issuePath.split(/[#]/);
|
||||
|
||||
gqlClient
|
||||
.mutate({
|
||||
mutation: issueMoveListMutation,
|
||||
variables: {
|
||||
projectPath: `${groupPath}/${project}`,
|
||||
projectPath: fullProjectPath,
|
||||
boardId: fullBoardId(boardId),
|
||||
iid: issueIid,
|
||||
fromListId: getIdFromGraphQLId(fromListId),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<script>
|
||||
import { mapActions, mapGetters, mapState } from 'vuex';
|
||||
import $ from 'jquery';
|
||||
import { GlTooltipDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
|
||||
import DiffTableCell from './diff_table_cell.vue';
|
||||
import { GlTooltipDirective, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
|
||||
import {
|
||||
MATCH_LINE_TYPE,
|
||||
NEW_LINE_TYPE,
|
||||
|
|
@ -13,11 +12,16 @@ import {
|
|||
PARALLEL_DIFF_VIEW_TYPE,
|
||||
NEW_NO_NEW_LINE_TYPE,
|
||||
EMPTY_CELL_TYPE,
|
||||
LINE_HOVER_CLASS_NAME,
|
||||
} from '../constants';
|
||||
import { __ } from '~/locale';
|
||||
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
|
||||
import DiffGutterAvatars from './diff_gutter_avatars.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DiffTableCell,
|
||||
GlIcon,
|
||||
DiffGutterAvatars,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
|
|
@ -51,10 +55,12 @@ export default {
|
|||
return {
|
||||
isLeftHover: false,
|
||||
isRightHover: false,
|
||||
isCommentButtonRendered: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('diffs', ['fileLineCoverage']),
|
||||
...mapGetters(['isLoggedIn']),
|
||||
...mapState({
|
||||
isHighlighted(state) {
|
||||
if (this.isCommented) return true;
|
||||
|
|
@ -66,12 +72,15 @@ export default {
|
|||
return lineCode ? lineCode === state.diffs.highlightedRow : false;
|
||||
},
|
||||
}),
|
||||
isContextLine() {
|
||||
isContextLineLeft() {
|
||||
return this.line.left && this.line.left.type === CONTEXT_LINE_TYPE;
|
||||
},
|
||||
isContextLineRight() {
|
||||
return this.line.right && this.line.right.type === CONTEXT_LINE_TYPE;
|
||||
},
|
||||
classNameMap() {
|
||||
return {
|
||||
[CONTEXT_LINE_CLASS_NAME]: this.isContextLine,
|
||||
[CONTEXT_LINE_CLASS_NAME]: this.isContextLineLeft,
|
||||
[PARALLEL_DIFF_VIEW_TYPE]: true,
|
||||
};
|
||||
},
|
||||
|
|
@ -98,6 +107,129 @@ export default {
|
|||
coverageState() {
|
||||
return this.fileLineCoverage(this.filePath, this.line.right.new_line);
|
||||
},
|
||||
classNameMapCellLeft() {
|
||||
const { type } = this.line.left;
|
||||
|
||||
return [
|
||||
type,
|
||||
{
|
||||
hll: this.isHighlighted,
|
||||
[LINE_HOVER_CLASS_NAME]:
|
||||
this.isLoggedIn && this.isLeftHover && !this.isContextLineLeft && !this.isMetaLineLeft,
|
||||
},
|
||||
];
|
||||
},
|
||||
classNameMapCellRight() {
|
||||
const { type } = this.line.right;
|
||||
|
||||
return [
|
||||
type,
|
||||
{
|
||||
hll: this.isHighlighted,
|
||||
[LINE_HOVER_CLASS_NAME]:
|
||||
this.isLoggedIn &&
|
||||
this.isRightHover &&
|
||||
!this.isContextLineRight &&
|
||||
!this.isMetaLineRight,
|
||||
},
|
||||
];
|
||||
},
|
||||
addCommentTooltipLeft() {
|
||||
const brokenSymlinks = this.line.left.commentsDisabled;
|
||||
let tooltip = __('Add a comment to this line');
|
||||
|
||||
if (brokenSymlinks) {
|
||||
if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
|
||||
tooltip = __(
|
||||
'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
|
||||
);
|
||||
} else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
|
||||
tooltip = __(
|
||||
'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
},
|
||||
addCommentTooltipRight() {
|
||||
const brokenSymlinks = this.line.right.commentsDisabled;
|
||||
let tooltip = __('Add a comment to this line');
|
||||
|
||||
if (brokenSymlinks) {
|
||||
if (brokenSymlinks.wasSymbolic || brokenSymlinks.isSymbolic) {
|
||||
tooltip = __(
|
||||
'Commenting on symbolic links that replace or are replaced by files is currently not supported.',
|
||||
);
|
||||
} else if (brokenSymlinks.wasReal || brokenSymlinks.isReal) {
|
||||
tooltip = __(
|
||||
'Commenting on files that replace or are replaced by symbolic links is currently not supported.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
},
|
||||
shouldRenderCommentButton() {
|
||||
if (!this.isCommentButtonRendered) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isLoggedIn) {
|
||||
const isDiffHead = parseBoolean(getParameterByName('diff_head'));
|
||||
return !isDiffHead || gon.features?.mergeRefHeadComments;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
shouldShowCommentButtonLeft() {
|
||||
return (
|
||||
this.isLeftHover &&
|
||||
!this.isContextLineLeft &&
|
||||
!this.isMetaLineLeft &&
|
||||
!this.hasDiscussionsLeft
|
||||
);
|
||||
},
|
||||
shouldShowCommentButtonRight() {
|
||||
return (
|
||||
this.isRightHover &&
|
||||
!this.isContextLineRight &&
|
||||
!this.isMetaLineRight &&
|
||||
!this.hasDiscussionsRight
|
||||
);
|
||||
},
|
||||
hasDiscussionsLeft() {
|
||||
return this.line.left.discussions && this.line.left.discussions.length > 0;
|
||||
},
|
||||
hasDiscussionsRight() {
|
||||
return this.line.right.discussions && this.line.right.discussions.length > 0;
|
||||
},
|
||||
lineHrefOld() {
|
||||
return `#${this.line.left.line_code || ''}`;
|
||||
},
|
||||
lineHrefNew() {
|
||||
return `#${this.line.right.line_code || ''}`;
|
||||
},
|
||||
lineCode() {
|
||||
return (
|
||||
(this.line.left && this.line.left.line_code) ||
|
||||
(this.line.right && this.line.right.line_code)
|
||||
);
|
||||
},
|
||||
isMetaLineLeft() {
|
||||
const { type } = this.line.left;
|
||||
|
||||
return (
|
||||
type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
|
||||
);
|
||||
},
|
||||
isMetaLineRight() {
|
||||
const { type } = this.line.right;
|
||||
|
||||
return (
|
||||
type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
|
||||
);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.newLineType = NEW_LINE_TYPE;
|
||||
|
|
@ -106,9 +238,26 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.scrollToLineIfNeededParallel(this.line);
|
||||
this.unwatchShouldShowCommentButton = this.$watch(
|
||||
vm => [vm.shouldShowCommentButtonLeft, vm.shouldShowCommentButtonRight].join(),
|
||||
newVal => {
|
||||
if (newVal) {
|
||||
this.isCommentButtonRendered = true;
|
||||
this.unwatchShouldShowCommentButton();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unwatchShouldShowCommentButton();
|
||||
},
|
||||
methods: {
|
||||
...mapActions('diffs', ['scrollToLineIfNeededParallel']),
|
||||
...mapActions('diffs', [
|
||||
'scrollToLineIfNeededParallel',
|
||||
'showCommentForm',
|
||||
'setHighlightedRow',
|
||||
'toggleLineDiscussions',
|
||||
]),
|
||||
handleMouseMove(e) {
|
||||
const isHover = e.type === 'mouseover';
|
||||
const hoveringCell = e.target.closest('td');
|
||||
|
|
@ -134,6 +283,9 @@ export default {
|
|||
table.addClass(`${lineClass}-selected`);
|
||||
}
|
||||
},
|
||||
handleCommentButton(line) {
|
||||
this.showCommentForm({ lineCode: line.line_code, fileHash: this.fileHash });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -146,18 +298,46 @@ export default {
|
|||
@mouseout="handleMouseMove"
|
||||
>
|
||||
<template v-if="line.left && !isMatchLineLeft">
|
||||
<diff-table-cell
|
||||
:file-hash="fileHash"
|
||||
:line="line.left"
|
||||
:line-type="oldLineType"
|
||||
:is-bottom="isBottom"
|
||||
:is-hover="isLeftHover"
|
||||
:is-highlighted="isHighlighted"
|
||||
:show-comment-button="true"
|
||||
:diff-view-type="parallelDiffViewType"
|
||||
line-position="left"
|
||||
class="diff-line-num old_line"
|
||||
/>
|
||||
<td ref="oldTd" :class="classNameMapCellLeft" class="diff-line-num old_line">
|
||||
<span
|
||||
v-if="shouldRenderCommentButton"
|
||||
ref="addNoteTooltipLeft"
|
||||
v-gl-tooltip
|
||||
class="add-diff-note tooltip-wrapper"
|
||||
:title="addCommentTooltipLeft"
|
||||
>
|
||||
<button
|
||||
v-show="shouldShowCommentButtonLeft"
|
||||
ref="addDiffNoteButtonLeft"
|
||||
type="button"
|
||||
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||||
:disabled="line.left.commentsDisabled"
|
||||
@click="handleCommentButton(line.left)"
|
||||
>
|
||||
<gl-icon :size="12" name="comment" />
|
||||
</button>
|
||||
</span>
|
||||
<a
|
||||
v-if="line.left.old_line"
|
||||
ref="lineNumberRefOld"
|
||||
:data-linenumber="line.left.old_line"
|
||||
:href="lineHrefOld"
|
||||
@click="setHighlightedRow(lineCode)"
|
||||
>
|
||||
</a>
|
||||
<diff-gutter-avatars
|
||||
v-if="hasDiscussionsLeft"
|
||||
:discussions="line.left.discussions"
|
||||
:discussions-expanded="line.left.discussionsExpanded"
|
||||
@toggleLineDiscussions="
|
||||
toggleLineDiscussions({
|
||||
lineCode: line.left.line_code,
|
||||
fileHash,
|
||||
expanded: !line.left.discussionsExpanded,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
<td :class="parallelViewLeftLineType" class="line-coverage left-side"></td>
|
||||
<td
|
||||
:id="line.left.line_code"
|
||||
|
|
@ -173,18 +353,46 @@ export default {
|
|||
<td class="line_content with-coverage parallel left-side empty-cell"></td>
|
||||
</template>
|
||||
<template v-if="line.right && !isMatchLineRight">
|
||||
<diff-table-cell
|
||||
:file-hash="fileHash"
|
||||
:line="line.right"
|
||||
:line-type="newLineType"
|
||||
:is-bottom="isBottom"
|
||||
:is-hover="isRightHover"
|
||||
:is-highlighted="isHighlighted"
|
||||
:show-comment-button="true"
|
||||
:diff-view-type="parallelDiffViewType"
|
||||
line-position="right"
|
||||
class="diff-line-num new_line"
|
||||
/>
|
||||
<td ref="newTd" :class="classNameMapCellRight" class="diff-line-num new_line">
|
||||
<span
|
||||
v-if="shouldRenderCommentButton"
|
||||
ref="addNoteTooltipRight"
|
||||
v-gl-tooltip
|
||||
class="add-diff-note tooltip-wrapper"
|
||||
:title="addCommentTooltipRight"
|
||||
>
|
||||
<button
|
||||
v-show="shouldShowCommentButtonRight"
|
||||
ref="addDiffNoteButtonRight"
|
||||
type="button"
|
||||
class="add-diff-note note-button js-add-diff-note-button qa-diff-comment"
|
||||
:disabled="line.right.commentsDisabled"
|
||||
@click="handleCommentButton(line.right)"
|
||||
>
|
||||
<gl-icon :size="12" name="comment" />
|
||||
</button>
|
||||
</span>
|
||||
<a
|
||||
v-if="line.right.new_line"
|
||||
ref="lineNumberRefNew"
|
||||
:data-linenumber="line.right.new_line"
|
||||
:href="lineHrefNew"
|
||||
@click="setHighlightedRow(lineCode)"
|
||||
>
|
||||
</a>
|
||||
<diff-gutter-avatars
|
||||
v-if="hasDiscussionsRight"
|
||||
:discussions="line.right.discussions"
|
||||
:discussions-expanded="line.right.discussionsExpanded"
|
||||
@toggleLineDiscussions="
|
||||
toggleLineDiscussions({
|
||||
lineCode: line.right.line_code,
|
||||
fileHash,
|
||||
expanded: !line.right.discussionsExpanded,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
v-gl-tooltip.hover
|
||||
:title="coverageState.text"
|
||||
|
|
|
|||
|
|
@ -468,7 +468,6 @@ export default {
|
|||
|
||||
<component
|
||||
:is="descriptionComponent"
|
||||
v-if="state.descriptionHtml"
|
||||
:can-update="canUpdate"
|
||||
:description-html="state.descriptionHtml"
|
||||
:description-text="state.descriptionText"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
query getAlert($iid: String!, $fullPath: ID!) {
|
||||
project(fullPath: $fullPath) {
|
||||
issue(iid: $iid) {
|
||||
alertManagementAlert {
|
||||
iid
|
||||
title
|
||||
detailsUrl
|
||||
severity
|
||||
status
|
||||
startedAt
|
||||
eventCount
|
||||
monitoringTool
|
||||
service
|
||||
description
|
||||
endedAt
|
||||
details
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,20 @@
|
|||
<script>
|
||||
import { GlLink } from '@gitlab/ui';
|
||||
import { formatDate } from '~/lib/utils/datetime_utility';
|
||||
import getHighlightBarInfo from './graphql/queries/get_highlight_bar_info.graphql';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlLink,
|
||||
},
|
||||
inject: ['fullPath', 'iid'],
|
||||
apollo: {
|
||||
props: {
|
||||
alert: {
|
||||
query: getHighlightBarInfo,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.fullPath,
|
||||
iid: this.iid,
|
||||
};
|
||||
},
|
||||
update: data => data.project?.issue?.alertManagementAlert,
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
startTime() {
|
||||
return formatDate(this.alert.createdAt, 'yyyy-mm-dd Z');
|
||||
return formatDate(this.alert.startedAt, 'yyyy-mm-dd Z');
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -30,7 +22,6 @@ export default {
|
|||
|
||||
<template>
|
||||
<div
|
||||
v-if="alert"
|
||||
class="gl-border-solid gl-border-1 gl-border-gray-100 gl-p-5 gl-mb-3 gl-rounded-base gl-display-flex gl-justify-content-space-between"
|
||||
>
|
||||
<div class="text-truncate gl-pr-3">
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
query getHighlightBarInfo($iid: String!, $fullPath: ID!) {
|
||||
project(fullPath: $fullPath) {
|
||||
issue(iid: $iid) {
|
||||
alertManagementAlert {
|
||||
title
|
||||
detailsUrl
|
||||
createdAt
|
||||
eventCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,71 @@
|
|||
<script>
|
||||
import { GlTab, GlTabs } from '@gitlab/ui';
|
||||
import DescriptionComponent from '../description.vue';
|
||||
import HighlightBar from './highlight_bar/higlight_bar.vue';
|
||||
import HighlightBar from './highlight_bar.vue';
|
||||
import createFlash from '~/flash';
|
||||
import { s__ } from '~/locale';
|
||||
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
|
||||
|
||||
import getAlert from './graphql/queries/get_alert.graphql';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AlertDetailsTable,
|
||||
DescriptionComponent,
|
||||
GlTab,
|
||||
GlTabs,
|
||||
DescriptionComponent,
|
||||
HighlightBar,
|
||||
},
|
||||
inject: ['fullPath', 'iid'],
|
||||
apollo: {
|
||||
alert: {
|
||||
query: getAlert,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.fullPath,
|
||||
iid: this.iid,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
return data?.project?.issue?.alertManagementAlert;
|
||||
},
|
||||
error() {
|
||||
createFlash({
|
||||
message: s__('Incident|There was an issue loading alert data. Please try again.'),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
alert: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
loading() {
|
||||
return this.$apollo.queries.alert.loading;
|
||||
},
|
||||
alertTableFields() {
|
||||
if (this.alert) {
|
||||
const { detailsUrl, __typename, ...restDetails } = this.alert;
|
||||
return restDetails;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<gl-tabs content-class="gl-reset-line-height" class="gl-mt-n3" data-testid="incident-tabs">
|
||||
<gl-tab :title="__('Summary')">
|
||||
<highlight-bar />
|
||||
<gl-tab :title="s__('Incident|Summary')">
|
||||
<highlight-bar v-if="alert" :alert="alert" />
|
||||
<description-component v-bind="$attrs" />
|
||||
</gl-tab>
|
||||
<gl-tab v-if="alert" class="alert-management-details" :title="s__('Incident|Alert details')">
|
||||
<alert-details-table :alert="alertTableFields" :loading="loading" />
|
||||
</gl-tab>
|
||||
</gl-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
/* eslint-disable vue/no-v-html */
|
||||
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { GlButton, GlTooltipDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
|
||||
import animateMixin from '../mixins/animate';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
|
|
@ -10,6 +9,7 @@ export default {
|
|||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
SafeHtml,
|
||||
},
|
||||
mixins: [animateMixin],
|
||||
props: {
|
||||
|
|
@ -65,13 +65,13 @@ export default {
|
|||
<template>
|
||||
<div class="title-container">
|
||||
<h2
|
||||
v-safe-html="titleHtml"
|
||||
:class="{
|
||||
'issue-realtime-pre-pulse': preAnimation,
|
||||
'issue-realtime-trigger-pulse': pulseAnimation,
|
||||
}"
|
||||
class="title qa-title"
|
||||
dir="auto"
|
||||
v-html="titleHtml"
|
||||
></h2>
|
||||
<gl-button
|
||||
v-if="showInlineEditButton && canUpdate"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import { GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { GlIcon, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
|
||||
import PackageTags from '../../shared/components/package_tags.vue';
|
||||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
|
||||
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
|
|
@ -12,9 +13,9 @@ export default {
|
|||
components: {
|
||||
TitleArea,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
PackageTags,
|
||||
MetadataItem,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
|
|
@ -54,35 +55,24 @@ export default {
|
|||
</template>
|
||||
|
||||
<template v-if="packageTypeDisplay" #metadata_type>
|
||||
<gl-icon name="package" class="gl-text-gray-500 gl-mr-3" />
|
||||
<span data-testid="package-type" class="gl-font-weight-bold">{{ packageTypeDisplay }}</span>
|
||||
<metadata-item data-testid="package-type" icon="package" :text="packageTypeDisplay" />
|
||||
</template>
|
||||
|
||||
<template #metadata_size>
|
||||
<gl-icon name="disk" class="gl-text-gray-500 gl-mr-3" />
|
||||
<span data-testid="package-size" class="gl-font-weight-bold">{{ totalSize }}</span>
|
||||
<metadata-item data-testid="package-size" icon="disk" :text="totalSize" />
|
||||
</template>
|
||||
|
||||
<template v-if="packagePipeline" #metadata_pipeline>
|
||||
<gl-icon name="review-list" class="gl-text-gray-500 gl-mr-3" />
|
||||
<gl-link
|
||||
<metadata-item
|
||||
data-testid="pipeline-project"
|
||||
:href="packagePipeline.project.web_url"
|
||||
class="gl-font-weight-bold gl-str-truncated"
|
||||
>
|
||||
{{ packagePipeline.project.name }}
|
||||
</gl-link>
|
||||
icon="review-list"
|
||||
:text="packagePipeline.project.name"
|
||||
:link="packagePipeline.project.web_url"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="packagePipeline" #metadata_ref>
|
||||
<gl-icon name="branch" data-testid="package-ref-icon" class="gl-text-gray-500 gl-mr-3" />
|
||||
<span
|
||||
v-gl-tooltip
|
||||
data-testid="package-ref"
|
||||
class="gl-font-weight-bold gl-str-truncated mw-xs"
|
||||
:title="packagePipeline.ref"
|
||||
>{{ packagePipeline.ref }}</span
|
||||
>
|
||||
<metadata-item data-testid="package-ref" icon="branch" :text="packagePipeline.ref" />
|
||||
</template>
|
||||
|
||||
<template v-if="hasTagsToDisplay" #metadata_tags>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<script>
|
||||
import { GlSprintf, GlLink, GlIcon } from '@gitlab/ui';
|
||||
import { GlSprintf, GlLink } from '@gitlab/ui';
|
||||
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
|
||||
import { n__ } from '~/locale';
|
||||
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
|
||||
import { n__, sprintf } from '~/locale';
|
||||
import { approximateDuration, calculateRemainingMilliseconds } from '~/lib/utils/datetime_utility';
|
||||
|
||||
import {
|
||||
|
|
@ -14,10 +15,10 @@ import {
|
|||
|
||||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
GlSprintf,
|
||||
GlLink,
|
||||
TitleArea,
|
||||
MetadataItem,
|
||||
},
|
||||
props: {
|
||||
expirationPolicy: {
|
||||
|
|
@ -58,11 +59,12 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
imagesCountText() {
|
||||
return n__(
|
||||
const pluralisedString = n__(
|
||||
'ContainerRegistry|%{count} Image repository',
|
||||
'ContainerRegistry|%{count} Image repositories',
|
||||
this.imagesCount,
|
||||
);
|
||||
return sprintf(pluralisedString, { count: this.imagesCount });
|
||||
},
|
||||
timeTillRun() {
|
||||
const difference = calculateRemainingMilliseconds(this.expirationPolicy?.next_run_at);
|
||||
|
|
@ -73,7 +75,7 @@ export default {
|
|||
},
|
||||
expirationPolicyText() {
|
||||
return this.expirationPolicyEnabled
|
||||
? EXPIRATION_POLICY_WILL_RUN_IN
|
||||
? sprintf(EXPIRATION_POLICY_WILL_RUN_IN, { time: this.timeTillRun })
|
||||
: EXPIRATION_POLICY_DISABLED_TEXT;
|
||||
},
|
||||
showExpirationPolicyTip() {
|
||||
|
|
@ -92,24 +94,21 @@ export default {
|
|||
<slot name="commands"></slot>
|
||||
</template>
|
||||
<template #metadata_count>
|
||||
<span v-if="imagesCount" data-testid="images-count">
|
||||
<gl-icon class="gl-mr-1" name="container-image" />
|
||||
<gl-sprintf :message="imagesCountText">
|
||||
<template #count>
|
||||
{{ imagesCount }}
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
<metadata-item
|
||||
v-if="imagesCount"
|
||||
data-testid="images-count"
|
||||
icon="container-image"
|
||||
:text="imagesCountText"
|
||||
/>
|
||||
</template>
|
||||
<template #metadata_exp_policies>
|
||||
<span v-if="!hideExpirationPolicyData" data-testid="expiration-policy">
|
||||
<gl-icon class="gl-mr-1" name="expire" />
|
||||
<gl-sprintf :message="expirationPolicyText">
|
||||
<template #time>
|
||||
{{ timeTillRun }}
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</span>
|
||||
<metadata-item
|
||||
v-if="!hideExpirationPolicyData"
|
||||
data-testid="expiration-policy"
|
||||
icon="expire"
|
||||
:text="expirationPolicyText"
|
||||
size="xl"
|
||||
/>
|
||||
</template>
|
||||
</title-area>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
},
|
||||
},
|
||||
tableHeader: {
|
||||
[s__('AlertManagement|Full Alert Payload')]: s__('AlertManagement|Value'),
|
||||
[s__('AlertManagement|Key')]: s__('AlertManagement|Value'),
|
||||
},
|
||||
computed: {
|
||||
items() {
|
||||
|
|
@ -33,7 +33,7 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<gl-table
|
||||
class="alert-management-details-table"
|
||||
class="alert-management-details-table gl-mb-0!"
|
||||
:busy="loading"
|
||||
:empty-text="s__('AlertManagement|No alert data to display.')"
|
||||
:items="items"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
<script>
|
||||
import { GlIcon, GlLink } from '@gitlab/ui';
|
||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
|
||||
|
||||
export default {
|
||||
name: 'MetadataItem',
|
||||
components: {
|
||||
GlIcon,
|
||||
GlLink,
|
||||
TooltipOnTruncate,
|
||||
},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
link: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 's',
|
||||
validator(value) {
|
||||
return !value || ['xs', 's', 'm', 'l', 'xl'].includes(value);
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
sizeClass() {
|
||||
return `mw-${this.size}`;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-inline-flex gl-align-items-center">
|
||||
<gl-icon v-if="icon" :name="icon" class="gl-text-gray-500 gl-mr-3" />
|
||||
<tooltip-on-truncate v-if="link" :title="text" class="gl-text-truncate" :class="sizeClass">
|
||||
<gl-link :href="link" class="gl-font-weight-bold">
|
||||
{{ text }}
|
||||
</gl-link>
|
||||
</tooltip-on-truncate>
|
||||
<div
|
||||
v-else
|
||||
data-testid="metadata-item-text"
|
||||
class="gl-font-weight-bold gl-display-inline-flex"
|
||||
:class="sizeClass"
|
||||
>
|
||||
<tooltip-on-truncate :title="text" class="gl-text-truncate">
|
||||
{{ text }}
|
||||
</tooltip-on-truncate>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -6,7 +6,10 @@
|
|||
@include gl-border-0;
|
||||
@include gl-p-5;
|
||||
border-color: transparent;
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
div {
|
||||
|
|
@ -31,6 +34,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
&::after {
|
||||
content: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ $status-box-line-height: 26px;
|
|||
|
||||
.milestone-detail {
|
||||
border-bottom: 1px solid $border-color;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ module Repositories
|
|||
end
|
||||
|
||||
def download_objects!
|
||||
existing_oids = project.all_lfs_objects_oids(oids: objects_oids)
|
||||
existing_oids = project.lfs_objects_oids(oids: objects_oids)
|
||||
|
||||
objects.each do |object|
|
||||
if existing_oids.include?(object[:oid])
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ module Types
|
|||
graphql_name 'AlertManagementAlert'
|
||||
description "Describes an alert from the project's Alert Management"
|
||||
|
||||
present_using ::AlertManagement::AlertPresenter
|
||||
|
||||
implements(Types::Notes::NoteableType)
|
||||
|
||||
authorize :read_alert_management_alert
|
||||
|
|
@ -120,10 +122,6 @@ module Types
|
|||
def notes
|
||||
object.ordered_notes
|
||||
end
|
||||
|
||||
def runbook
|
||||
object.parsed_payload.runbook
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -58,10 +58,6 @@ module DashboardHelper
|
|||
links += [:activity, :milestones]
|
||||
end
|
||||
|
||||
if can?(current_user, :read_instance_statistics)
|
||||
links << :analytics
|
||||
end
|
||||
|
||||
links
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ module NavHelper
|
|||
end
|
||||
|
||||
def has_extra_nav_icons?
|
||||
Gitlab::Sherlock.enabled? || can?(current_user, :read_instance_statistics) || current_user.admin?
|
||||
Gitlab::Sherlock.enabled? || current_user.admin?
|
||||
end
|
||||
|
||||
def page_has_markdown?
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ module AlertManagement
|
|||
end
|
||||
|
||||
delegate :iid, to: :issue, prefix: true, allow_nil: true
|
||||
delegate :metrics_dashboard_url, :details_url, :details, to: :present
|
||||
delegate :details_url, to: :present
|
||||
|
||||
scope :for_iid, -> (iid) { where(iid: iid) }
|
||||
scope :for_status, -> (status) { where(status: status) }
|
||||
|
|
@ -218,12 +218,6 @@ module AlertManagement
|
|||
end
|
||||
end
|
||||
|
||||
def present
|
||||
return super(presenter_class: AlertManagement::PrometheusAlertPresenter) if prometheus?
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def hook_data
|
||||
|
|
|
|||
|
|
@ -1469,46 +1469,6 @@ class Project < ApplicationRecord
|
|||
forked_from_project || fork_network&.root_project
|
||||
end
|
||||
|
||||
# TODO: Remove this method once all LfsObjectsProject records are backfilled
|
||||
# for forks.
|
||||
#
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/122002 for more info.
|
||||
def lfs_storage_project
|
||||
@lfs_storage_project ||= begin
|
||||
result = self
|
||||
|
||||
# TODO: Make this go to the fork_network root immediately
|
||||
# dependant on the discussion in: https://gitlab.com/gitlab-org/gitlab-foss/issues/39769
|
||||
result = result.fork_source while result&.forked?
|
||||
|
||||
result || self
|
||||
end
|
||||
end
|
||||
|
||||
# This will return all `lfs_objects` that are accessible to the project and
|
||||
# the fork source. This is needed since older forks won't have access to some
|
||||
# LFS objects directly and have to get it from the fork source.
|
||||
#
|
||||
# TODO: Remove this method once all LfsObjectsProject records are backfilled
|
||||
# for forks. At that point, projects can look at their own `lfs_objects`.
|
||||
#
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/122002 for more info.
|
||||
def all_lfs_objects
|
||||
LfsObject
|
||||
.distinct
|
||||
.joins(:lfs_objects_projects)
|
||||
.where(lfs_objects_projects: { project_id: [self, lfs_storage_project] })
|
||||
end
|
||||
|
||||
# TODO: Remove this method once all LfsObjectsProject records are backfilled
|
||||
# for forks. At that point, projects can look at their own `lfs_objects` so
|
||||
# `lfs_objects_oids` can be used instead.
|
||||
#
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/122002 for more info.
|
||||
def all_lfs_objects_oids(oids: [])
|
||||
oids(all_lfs_objects, oids: oids)
|
||||
end
|
||||
|
||||
def lfs_objects_oids(oids: [])
|
||||
oids(lfs_objects, oids: oids)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ class GlobalPolicy < BasePolicy
|
|||
rule { admin }.policy do
|
||||
enable :read_custom_attribute
|
||||
enable :update_custom_attribute
|
||||
enable :read_instance_statistics
|
||||
end
|
||||
|
||||
# We can't use `read_statistics` because the user may have different permissions for different projects
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ module AlertManagement
|
|||
include IncidentManagement::Settings
|
||||
include ActionView::Helpers::UrlHelper
|
||||
|
||||
MARKDOWN_LINE_BREAK = " \n".freeze
|
||||
MARKDOWN_LINE_BREAK = " \n"
|
||||
HORIZONTAL_LINE = "\n\n---\n\n"
|
||||
|
||||
delegate :metrics_dashboard_url, :runbook, to: :parsed_payload
|
||||
|
||||
def initialize(alert, _attributes = {})
|
||||
super
|
||||
|
|
@ -16,28 +19,17 @@ module AlertManagement
|
|||
end
|
||||
|
||||
def issue_description
|
||||
horizontal_line = "\n\n---\n\n"
|
||||
|
||||
[
|
||||
issue_summary_markdown,
|
||||
alert_markdown,
|
||||
incident_management_setting.issue_template_content
|
||||
].compact.join(horizontal_line)
|
||||
].compact.join(HORIZONTAL_LINE)
|
||||
end
|
||||
|
||||
def start_time
|
||||
started_at&.strftime('%d %B %Y, %-l:%M%p (%Z)')
|
||||
end
|
||||
|
||||
def issue_summary_markdown
|
||||
<<~MARKDOWN.chomp
|
||||
#{metadata_list}
|
||||
#{alert_details}#{metric_embed_for_alert}
|
||||
MARKDOWN
|
||||
end
|
||||
|
||||
def metrics_dashboard_url; end
|
||||
|
||||
def details_url
|
||||
details_project_alert_management_url(project, alert.iid)
|
||||
end
|
||||
|
|
@ -49,15 +41,15 @@ module AlertManagement
|
|||
private
|
||||
|
||||
attr_reader :alert, :project
|
||||
delegate :alert_markdown, :full_query, to: :parsed_payload
|
||||
|
||||
def alerting_alert
|
||||
strong_memoize(:alerting_alert) do
|
||||
Gitlab::Alerting::Alert.new(project: project, payload: alert.payload).present
|
||||
end
|
||||
def issue_summary_markdown
|
||||
<<~MARKDOWN.chomp
|
||||
#{metadata_list}
|
||||
#{alert_details}#{metric_embed_for_alert}
|
||||
MARKDOWN
|
||||
end
|
||||
|
||||
def alert_markdown; end
|
||||
|
||||
def metadata_list
|
||||
metadata = []
|
||||
|
||||
|
|
@ -90,9 +82,9 @@ module AlertManagement
|
|||
.join(MARKDOWN_LINE_BREAK)
|
||||
end
|
||||
|
||||
def metric_embed_for_alert; end
|
||||
|
||||
def full_query; end
|
||||
def metric_embed_for_alert
|
||||
"\n[](#{metrics_dashboard_url})" if metrics_dashboard_url
|
||||
end
|
||||
|
||||
def list_item(key, value)
|
||||
"**#{key}:** #{value}".strip
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AlertManagement
|
||||
class PrometheusAlertPresenter < AlertManagement::AlertPresenter
|
||||
def metrics_dashboard_url
|
||||
alerting_alert.metrics_dashboard_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def alert_markdown
|
||||
alerting_alert.alert_markdown
|
||||
end
|
||||
|
||||
def metric_embed_for_alert
|
||||
alerting_alert.metric_embed_for_alert
|
||||
end
|
||||
|
||||
def full_query
|
||||
alerting_alert.full_query
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -42,11 +42,37 @@ module Projects
|
|||
end
|
||||
|
||||
def process_existing_alert(alert)
|
||||
alert.register_new_event!
|
||||
if am_alert_params[:ended_at].present?
|
||||
process_resolved_alert(alert)
|
||||
else
|
||||
alert.register_new_event!
|
||||
end
|
||||
|
||||
alert
|
||||
end
|
||||
|
||||
def process_resolved_alert(alert)
|
||||
return unless auto_close_incident?
|
||||
|
||||
if alert.resolve(am_alert_params[:ended_at])
|
||||
close_issue(alert.issue)
|
||||
end
|
||||
|
||||
alert
|
||||
end
|
||||
|
||||
def close_issue(issue)
|
||||
return if issue.blank? || issue.closed?
|
||||
|
||||
::Issues::CloseService
|
||||
.new(project, User.alert_bot)
|
||||
.execute(issue, system_note: false)
|
||||
|
||||
SystemNoteService.auto_resolve_prometheus_alert(issue, project, User.alert_bot) if issue.reset.closed?
|
||||
end
|
||||
|
||||
def create_alert
|
||||
alert = AlertManagement::Alert.create(am_alert_params)
|
||||
alert = AlertManagement::Alert.create(am_alert_params.except(:ended_at))
|
||||
alert.execute_services if alert.persisted?
|
||||
SystemNoteService.create_new_alert(alert, 'Generic Alert Endpoint')
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ module Projects
|
|||
class LfsDownloadService < BaseService
|
||||
SizeError = Class.new(StandardError)
|
||||
OidError = Class.new(StandardError)
|
||||
ResponseError = Class.new(StandardError)
|
||||
|
||||
LARGE_FILE_SIZE = 1.megabytes
|
||||
|
||||
attr_reader :lfs_download_object
|
||||
delegate :oid, :size, :credentials, :sanitized_url, to: :lfs_download_object, prefix: :lfs
|
||||
|
|
@ -19,6 +22,7 @@ module Projects
|
|||
def execute
|
||||
return unless project&.lfs_enabled? && lfs_download_object
|
||||
return error("LFS file with oid #{lfs_oid} has invalid attributes") unless lfs_download_object.valid?
|
||||
return link_existing_lfs_object! if Feature.enabled?(:lfs_link_existing_object, project, default_enabled: true) && lfs_size > LARGE_FILE_SIZE && lfs_object
|
||||
|
||||
wrap_download_errors do
|
||||
download_lfs_file!
|
||||
|
|
@ -29,7 +33,7 @@ module Projects
|
|||
|
||||
def wrap_download_errors(&block)
|
||||
yield
|
||||
rescue SizeError, OidError, StandardError => e
|
||||
rescue SizeError, OidError, ResponseError, StandardError => e
|
||||
error("LFS file with oid #{lfs_oid} could't be downloaded from #{lfs_sanitized_url}: #{e.message}")
|
||||
end
|
||||
|
||||
|
|
@ -56,15 +60,13 @@ module Projects
|
|||
|
||||
def download_and_save_file!(file)
|
||||
digester = Digest::SHA256.new
|
||||
response = Gitlab::HTTP.get(lfs_sanitized_url, download_headers) do |fragment|
|
||||
fetch_file do |fragment|
|
||||
digester << fragment
|
||||
file.write(fragment)
|
||||
|
||||
raise_size_error! if file.size > lfs_size
|
||||
end
|
||||
|
||||
raise StandardError, "Received error code #{response.code}" unless response.success?
|
||||
|
||||
raise_size_error! if file.size != lfs_size
|
||||
raise_oid_error! if digester.hexdigest != lfs_oid
|
||||
end
|
||||
|
|
@ -78,6 +80,12 @@ module Projects
|
|||
end
|
||||
end
|
||||
|
||||
def fetch_file(&block)
|
||||
response = Gitlab::HTTP.get(lfs_sanitized_url, download_headers, &block)
|
||||
|
||||
raise ResponseError, "Received error code #{response.code}" unless response.success?
|
||||
end
|
||||
|
||||
def with_tmp_file
|
||||
create_tmp_storage_dir
|
||||
|
||||
|
|
@ -123,6 +131,29 @@ module Projects
|
|||
|
||||
super
|
||||
end
|
||||
|
||||
def lfs_object
|
||||
@lfs_object ||= LfsObject.find_by_oid(lfs_oid)
|
||||
end
|
||||
|
||||
def link_existing_lfs_object!
|
||||
existing_file = lfs_object.file.open
|
||||
buffer_size = 0
|
||||
result = fetch_file do |fragment|
|
||||
unless fragment == existing_file.read(fragment.size)
|
||||
break error("LFS file with oid #{lfs_oid} cannot be linked with an existing LFS object")
|
||||
end
|
||||
|
||||
buffer_size += fragment.size
|
||||
break success if buffer_size > LARGE_FILE_SIZE
|
||||
end
|
||||
|
||||
project.lfs_objects << lfs_object
|
||||
|
||||
result
|
||||
ensure
|
||||
existing_file&.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,21 +2,13 @@
|
|||
|
||||
module Projects
|
||||
class UnlinkForkService < BaseService
|
||||
# If a fork is given, it:
|
||||
#
|
||||
# - Saves LFS objects to the root project
|
||||
# - Close existing MRs coming from it
|
||||
# - Is removed from the fork network
|
||||
#
|
||||
# If a root of fork(s) is given, it does the same,
|
||||
# but not updating LFS objects (there'll be no related root to cache it).
|
||||
# Close existing MRs coming from the project and remove it from the fork network
|
||||
def execute
|
||||
fork_network = @project.fork_network
|
||||
forked_from = @project.forked_from_project
|
||||
|
||||
return unless fork_network
|
||||
|
||||
save_lfs_objects
|
||||
|
||||
merge_requests = fork_network
|
||||
.merge_requests
|
||||
.opened
|
||||
|
|
@ -41,7 +33,7 @@ module Projects
|
|||
|
||||
# When the project getting out of the network is a node with parent
|
||||
# and children, both the parent and the node needs a cache refresh.
|
||||
[@project.forked_from_project, @project].compact.each do |project|
|
||||
[forked_from, @project].compact.each do |project|
|
||||
refresh_forks_count(project)
|
||||
end
|
||||
end
|
||||
|
|
@ -51,22 +43,5 @@ module Projects
|
|||
def refresh_forks_count(project)
|
||||
Projects::ForksCountService.new(project).refresh_cache
|
||||
end
|
||||
|
||||
# TODO: Remove this method once all LfsObjectsProject records are backfilled
|
||||
# for forks.
|
||||
#
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/122002 for more info.
|
||||
def save_lfs_objects
|
||||
return unless @project.forked?
|
||||
|
||||
lfs_storage_project = @project.lfs_storage_project
|
||||
|
||||
return unless lfs_storage_project
|
||||
return if lfs_storage_project == @project # that project is being unlinked
|
||||
|
||||
lfs_storage_project.lfs_objects.find_each do |lfs_object|
|
||||
lfs_object.projects << @project unless lfs_object.projects.include?(@project)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@
|
|||
- if @group.new_record?
|
||||
.form-group.row
|
||||
.offset-sm-2.col-sm-10
|
||||
.alert.alert-info
|
||||
= render 'shared/group_tips'
|
||||
.gl-alert.gl-alert-info
|
||||
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
|
||||
.gl-alert-body
|
||||
= render 'shared/group_tips'
|
||||
.form-actions
|
||||
= f.submit _('Create group'), class: "btn btn-success"
|
||||
= link_to _('Cancel'), admin_groups_path, class: "btn btn-cancel"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
- project = local_assigns.fetch(:project)
|
||||
- return unless project.delete_error.present?
|
||||
|
||||
.project-deletion-failed-message.alert.alert-warning
|
||||
This project was scheduled for deletion, but failed with the following message:
|
||||
= project.delete_error
|
||||
.project-deletion-failed-message.gl-alert.gl-alert-warning
|
||||
= sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
|
||||
.gl-alert-body
|
||||
This project was scheduled for deletion, but failed with the following message:
|
||||
= project.delete_error
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
- page_title _("Edit"), @blob.path, @ref
|
||||
|
||||
- if @conflict
|
||||
.alert.alert-danger
|
||||
Someone edited the file the same time you did. Please check out
|
||||
= link_to "the file", project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer'
|
||||
and make sure your changes will not unintentionally remove theirs.
|
||||
.gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5
|
||||
= sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
|
||||
.gl-alert-body
|
||||
Someone edited the file the same time you did. Please check out
|
||||
= link_to "the file", project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer', class: 'gl-link'
|
||||
and make sure your changes will not unintentionally remove theirs.
|
||||
|
||||
- if editing_ci_config? && show_web_ide_alert?
|
||||
#js-suggest-web-ide-ci{ data: { dismiss_endpoint: user_callouts_path, feature_id: UserCalloutsHelper::WEB_IDE_ALERT_DISMISSED, edit_path: ide_edit_path } }
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.detail-page-description.milestone-detail
|
||||
%h2.title{ data: { qa_selector: "milestone_title_content" } }
|
||||
%h2.gl-m-0{ data: { qa_selector: "milestone_title_content" } }
|
||||
= markdown_field(milestone, :title)
|
||||
|
||||
- if milestone.try(:description).present?
|
||||
%div{ data: { qa_selector: "milestone_description_content" } }
|
||||
.description.md
|
||||
.description.md.gl-px-0.gl-pt-4.gl-border-1.gl-border-t-solid.gl-border-gray-100
|
||||
= markdown_field(milestone, :description)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class IssuePlacementWorker
|
|||
QUERY_LIMIT = 100
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def perform(issue_id)
|
||||
def perform(issue_id, project_id = nil)
|
||||
issue = Issue.id_in(issue_id).first
|
||||
return unless issue
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
|
|||
def link_lfs_objects(source_project, target_project)
|
||||
Projects::LfsPointers::LfsLinkService
|
||||
.new(target_project)
|
||||
.execute(source_project.all_lfs_objects_oids)
|
||||
.execute(source_project.lfs_objects_oids)
|
||||
rescue Projects::LfsPointers::LfsLinkService::TooManyOidsError
|
||||
raise_fork_failure(
|
||||
source_project,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Automatically resolve alert when receiving end time
|
||||
merge_request: 41648
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace bootstrap alerts in app/views/admin/groups/_form.html.haml
|
||||
merge_request: 41375
|
||||
author: Gilang Gumilar
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace bootstrap alerts in app/views/projects/_deletion_failed.html.haml
|
||||
merge_request: 41344
|
||||
author: Gilang Gumilar
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace bootstrap alerts in app/views/projects/blob/edit.html.haml
|
||||
merge_request: 41298
|
||||
author: Gilang Gumilar
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update visual styling of container registry metadata
|
||||
merge_request: 42202
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix max seats used not updated in billing summary
|
||||
merge_request: 42184
|
||||
author:
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Verify only 1mb of existing LFS object to improve LfsDownloadService performance
|
||||
merge_request: 41770
|
||||
author:
|
||||
type: performance
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Jdb/refactor parallel diff table row
|
||||
merge_request: 41606
|
||||
author:
|
||||
type: performance
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix spacing and borders in milestone title and description
|
||||
merge_request: 40649
|
||||
author:
|
||||
type: fixed
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Surface alert details in a tab on incidents
|
||||
merge_request: 41850
|
||||
author:
|
||||
type: added
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Upgrade vendored Dockerfile template to buster
|
||||
merge_request: 42169
|
||||
author: Takuya Noguchi
|
||||
type: other
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: additional_snowplow_tracking
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ajax_new_deploy_token
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: allow_group_deploy_token
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: allow_possible_spam
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: allow_unsafe_ruby_regexp
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: api_kaminari_count_with_limit
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: application_settings_tokens_optional_encryption
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: approval_suggestions
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: approvals_commented_by
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: archive_rate_limit
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: artifacts_management_page
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: async_commit_diff_files
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: auto_create_cluster_management_project
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: auto_devops_banner_disabled
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: backfill_partitioned_audit_events
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: batch_suggestions
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: boards_with_swimlanes
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: branch_list_keyset_pagination
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: branch_push_merge_commit_analyze
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: broadcast_issue_updates
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: build_service_proxy
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: builds
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: bulk_update_health_status
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: burnup_charts
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: chatops
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_artifacts_exclude
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_build_metadata_config
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_bulk_insert_on_create
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_daily_code_coverage
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_disable_validates_dependencies
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_download_daily_code_coverage
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_dynamic_child_pipeline
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_enable_live_trace
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_instance_variables_ui
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_job_heartbeats_runner
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_job_jwt
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_key_autocomplete
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_lint_creates_pipeline_with_dry_run
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_pipeline_latest
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_pipeline_rewind_iid
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_pipeline_status_omit_commit_sha_in_cache_key
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_raise_job_rules_without_workflow_rules_warning
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_runners_tokens_optional_encryption
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_skip_persistent_ref_existence_check
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_store_pipeline_messages
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_synchronous_artifact_parsing
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_update_queues_for_online_runners
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: ci_yaml_limit_size
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: cleanup_lfs_during_gc
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: cluster_management_project
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: clusters_list_redesign
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: container_registry_api
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: container_registry_cleanup
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: container_registry_fast_tag_delete
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: context_commits
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: create_cloud_run_clusters
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: dashboard_pipeline_status
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue