Skip to content

Commit 3c51952

Browse files
author
GitLab Bot
committed
Add latest changes from gitlab-org/gitlab@master
1 parent c40b751 commit 3c51952

File tree

68 files changed

+1385
-508
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1385
-508
lines changed

.eslintrc.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,6 @@ overrides:
193193
'@graphql-eslint/no-unused-fragments': error
194194
'@graphql-eslint/no-duplicate-fields': error
195195
- files:
196-
- 'spec/contracts/consumer/**/*'
196+
- '{,ee/}spec/contracts/consumer/**/*'
197197
rules:
198198
'@gitlab/require-i18n-strings': off

app/assets/javascripts/admin/users/components/actions/ban.vue

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ const messageHtml = `
1111
<ul>
1212
<li>${s__("AdminUsers|The user can't log in.")}</li>
1313
<li>${s__("AdminUsers|The user can't access git repositories.")}</li>
14-
<li>${s__(
15-
'AdminUsers|Issues and merge requests authored by this user are hidden from other users.',
16-
)}</li>
14+
<li>${s__('AdminUsers|Issues authored by this user are hidden from other users.')}</li>
1715
</ul>
1816
<p>${s__('AdminUsers|You can unban their account in the future. Their data remains intact.')}</p>
1917
<p>${sprintf(

app/assets/javascripts/issuable/components/issuable_header_warnings.vue

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script>
22
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
33
import { mapGetters } from 'vuex';
4-
import { sprintf, __ } from '~/locale';
4+
import { __ } from '~/locale';
55
import { IssuableType, WorkspaceType } from '~/issues/constants';
66
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
77
import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
@@ -40,9 +40,7 @@ export default {
4040
iconName: 'spam',
4141
visible: this.hidden,
4242
dataTestId: 'hidden',
43-
tooltip: sprintf(__('This %{issuable} is hidden because its author has been banned'), {
44-
issuable: this.getNoteableData.targetType.replace('_', ' '),
45-
}),
43+
tooltip: __('This issue is hidden because its author has been banned'),
4644
},
4745
];
4846
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
<script>
2+
/**
3+
* Common component to render a system note, icon and user information.
4+
*
5+
* This component need not be used with any store neither has any vuex dependency
6+
*
7+
* @example
8+
* <system-note
9+
* :note="{
10+
* id: String,
11+
* author: Object,
12+
* createdAt: String,
13+
* bodyHtml: String,
14+
* systemNoteIconName: String
15+
* }"
16+
* />
17+
*/
18+
import { GlButton, GlSkeletonLoader, GlTooltipDirective, GlIcon } from '@gitlab/ui';
19+
import $ from 'jquery';
20+
import SafeHtml from '~/vue_shared/directives/safe_html';
21+
import descriptionVersionHistoryMixin from 'ee_else_ce/notes/mixins/description_version_history';
22+
import '~/behaviors/markdown/render_gfm';
23+
import axios from '~/lib/utils/axios_utils';
24+
import { getLocationHash } from '~/lib/utils/url_utility';
25+
import { __ } from '~/locale';
26+
import NoteHeader from '~/notes/components/note_header.vue';
27+
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
28+
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
29+
30+
const MAX_VISIBLE_COMMIT_LIST_COUNT = 3;
31+
32+
export default {
33+
i18n: {
34+
deleteButtonLabel: __('Remove description history'),
35+
},
36+
name: 'SystemNote',
37+
components: {
38+
GlIcon,
39+
NoteHeader,
40+
TimelineEntryItem,
41+
GlButton,
42+
GlSkeletonLoader,
43+
},
44+
directives: {
45+
GlTooltip: GlTooltipDirective,
46+
SafeHtml,
47+
},
48+
mixins: [descriptionVersionHistoryMixin, glFeatureFlagsMixin()],
49+
props: {
50+
note: {
51+
type: Object,
52+
required: true,
53+
},
54+
},
55+
data() {
56+
return {
57+
expanded: false,
58+
lines: [],
59+
showLines: false,
60+
loadingDiff: false,
61+
isLoadingDescriptionVersion: false,
62+
};
63+
},
64+
computed: {
65+
targetNoteHash() {
66+
return getLocationHash();
67+
},
68+
descriptionVersions() {
69+
return [];
70+
},
71+
noteAnchorId() {
72+
return `note_${this.note.id}`;
73+
},
74+
isTargetNote() {
75+
return this.targetNoteHash === this.noteAnchorId;
76+
},
77+
toggleIcon() {
78+
return this.expanded ? 'chevron-up' : 'chevron-down';
79+
},
80+
// following 2 methods taken from code in `collapseLongCommitList` of notes.js:
81+
actionTextHtml() {
82+
return $(this.note.bodyHtml).unwrap().html();
83+
},
84+
hasMoreCommits() {
85+
return $(this.note.bodyHtml).filter('ul').children().length > MAX_VISIBLE_COMMIT_LIST_COUNT;
86+
},
87+
descriptionVersion() {
88+
return this.descriptionVersions[this.note.description_version_id];
89+
},
90+
},
91+
mounted() {
92+
$(this.$refs['gfm-content']).renderGFM();
93+
},
94+
methods: {
95+
fetchDescriptionVersion() {},
96+
softDeleteDescriptionVersion() {},
97+
98+
async toggleDiff() {
99+
this.showLines = !this.showLines;
100+
101+
if (!this.lines.length) {
102+
this.loadingDiff = true;
103+
const { data } = await axios.get(this.note.outdated_line_change_path);
104+
105+
this.lines = data.map((l) => ({
106+
...l,
107+
rich_text: l.rich_text.replace(/^[+ -]/, ''),
108+
}));
109+
this.loadingDiff = false;
110+
}
111+
},
112+
},
113+
safeHtmlConfig: {
114+
ADD_TAGS: ['use'], // to support icon SVGs
115+
},
116+
userColorSchemeClass: window.gon.user_color_scheme,
117+
};
118+
</script>
119+
120+
<template>
121+
<timeline-entry-item
122+
:id="noteAnchorId"
123+
:class="{ target: isTargetNote, 'pr-0': shouldShowDescriptionVersion }"
124+
class="note system-note note-wrapper"
125+
>
126+
<div class="timeline-icon"><gl-icon :name="note.systemNoteIconName" /></div>
127+
<div class="timeline-content">
128+
<div class="note-header">
129+
<note-header
130+
:author="note.author"
131+
:created-at="note.createdAt"
132+
:note-id="note.id"
133+
:is-system-note="true"
134+
>
135+
<span ref="gfm-content" v-safe-html="actionTextHtml"></span>
136+
<template
137+
v-if="canSeeDescriptionVersion || note.outdated_line_change_path"
138+
#extra-controls
139+
>
140+
&middot;
141+
<gl-button
142+
v-if="canSeeDescriptionVersion"
143+
variant="link"
144+
:icon="descriptionVersionToggleIcon"
145+
data-testid="compare-btn"
146+
class="gl-vertical-align-text-bottom gl-font-sm!"
147+
@click="toggleDescriptionVersion"
148+
>{{ __('Compare with previous version') }}</gl-button
149+
>
150+
<gl-button
151+
v-if="note.outdated_line_change_path"
152+
:icon="showLines ? 'chevron-up' : 'chevron-down'"
153+
variant="link"
154+
data-testid="outdated-lines-change-btn"
155+
class="gl-vertical-align-text-bottom gl-font-sm!"
156+
@click="toggleDiff"
157+
>
158+
{{ __('Compare changes') }}
159+
</gl-button>
160+
</template>
161+
</note-header>
162+
</div>
163+
<div class="note-body">
164+
<div
165+
v-safe-html="note.bodyHtml"
166+
:class="{ 'system-note-commit-list': hasMoreCommits, 'hide-shade': expanded }"
167+
class="note-text md"
168+
></div>
169+
<div v-if="hasMoreCommits" class="flex-list">
170+
<div class="system-note-commit-list-toggler flex-row" @click="expanded = !expanded">
171+
<gl-icon :name="toggleIcon" :size="8" class="gl-mr-2" />
172+
<span>{{ __('Toggle commit list') }}</span>
173+
</div>
174+
</div>
175+
<div v-if="shouldShowDescriptionVersion" class="description-version pt-2">
176+
<pre v-if="isLoadingDescriptionVersion" class="loading-state">
177+
<gl-skeleton-loader />
178+
</pre>
179+
<pre v-else v-safe-html="descriptionVersion" class="wrapper mt-2"></pre>
180+
<gl-button
181+
v-if="displayDeleteButton"
182+
v-gl-tooltip
183+
:title="$options.i18n.deleteButtonLabel"
184+
:aria-label="$options.i18n.deleteButtonLabel"
185+
variant="default"
186+
category="tertiary"
187+
icon="remove"
188+
class="delete-description-history"
189+
data-testid="delete-description-version-button"
190+
@click="deleteDescriptionVersion"
191+
/>
192+
</div>
193+
<div
194+
v-if="lines.length && showLines"
195+
class="diff-content outdated-lines-wrapper gl-border-solid gl-border-1 gl-border-gray-200 gl-mt-4 gl-rounded-small gl-overflow-hidden"
196+
>
197+
<table
198+
:class="$options.userColorSchemeClass"
199+
class="code js-syntax-highlight"
200+
data-testid="outdated-lines"
201+
>
202+
<tr v-for="line in lines" v-once :key="line.line_code" class="line_holder">
203+
<td
204+
:class="line.type"
205+
class="diff-line-num old_line gl-border-bottom-0! gl-border-top-0! gl-border-0! gl-rounded-0!"
206+
>
207+
{{ line.old_line }}
208+
</td>
209+
<td
210+
:class="line.type"
211+
class="diff-line-num new_line gl-border-bottom-0! gl-border-top-0!"
212+
>
213+
{{ line.new_line }}
214+
</td>
215+
<td
216+
:class="line.type"
217+
class="line_content gl-display-table-cell! gl-border-0! gl-rounded-0!"
218+
v-html="line.rich_text /* eslint-disable-line vue/no-v-html */"
219+
></td>
220+
</tr>
221+
</table>
222+
</div>
223+
<div v-else-if="showLines" class="mt-4">
224+
<gl-skeleton-loader />
225+
</div>
226+
</div>
227+
</div>
228+
</timeline-entry-item>
229+
</template>

app/assets/javascripts/work_items/components/work_item_detail.vue

+18-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
WIDGET_TYPE_ITERATION,
3131
WORK_ITEM_TYPE_VALUE_ISSUE,
3232
WORK_ITEM_TYPE_VALUE_OBJECTIVE,
33+
WIDGET_TYPE_NOTES,
3334
} from '../constants';
3435
3536
import workItemDatesSubscription from '../graphql/work_item_dates.subscription.graphql';
@@ -49,6 +50,7 @@ import WorkItemDueDate from './work_item_due_date.vue';
4950
import WorkItemAssignees from './work_item_assignees.vue';
5051
import WorkItemLabels from './work_item_labels.vue';
5152
import WorkItemMilestone from './work_item_milestone.vue';
53+
import WorkItemNotes from './work_item_notes.vue';
5254
5355
export default {
5456
i18n,
@@ -75,6 +77,7 @@ export default {
7577
WorkItemIteration: () => import('ee_component/work_items/components/work_item_iteration.vue'),
7678
WorkItemMilestone,
7779
WorkItemTree,
80+
WorkItemNotes,
7881
},
7982
mixins: [glFeatureFlagMixin()],
8083
inject: ['fullPath'],
@@ -258,6 +261,9 @@ export default {
258261
workItemMilestone() {
259262
return this.isWidgetPresent(WIDGET_TYPE_MILESTONE);
260263
},
264+
workItemNotes() {
265+
return this.isWidgetPresent(WIDGET_TYPE_NOTES);
266+
},
261267
fetchByIid() {
262268
return this.glFeatures.useIidInWorkItemsPath && parseBoolean(getParameterByName('iid_path'));
263269
},
@@ -428,7 +434,7 @@ export default {
428434
<div class="gl-display-flex gl-align-items-center" data-testid="work-item-body">
429435
<ul
430436
v-if="parentWorkItem"
431-
class="list-unstyled gl-display-flex gl-mr-auto gl-max-w-26 gl-md-max-w-50p gl-min-w-0 gl-mb-0"
437+
class="list-unstyled gl-display-flex gl-mr-auto gl-max-w-26 gl-md-max-w-50p gl-min-w-0 gl-mb-0 gl-z-index-0"
432438
data-testid="work-item-parent"
433439
>
434440
<li class="gl-ml-n4 gl-display-flex gl-align-items-center gl-overflow-hidden">
@@ -589,6 +595,17 @@ export default {
589595
@addWorkItemChild="addChild"
590596
@removeChild="removeChild"
591597
/>
598+
<template v-if="workItemsMvc2Enabled">
599+
<work-item-notes
600+
v-if="workItemNotes"
601+
:work-item-id="workItem.id"
602+
:query-variables="queryVariables"
603+
:full-path="fullPath"
604+
:fetch-by-iid="fetchByIid"
605+
class="gl-pt-5"
606+
@error="updateError = $event"
607+
/>
608+
</template>
592609
<gl-empty-state
593610
v-if="error"
594611
:title="$options.i18n.fetchErrorTitle"

app/assets/javascripts/work_items/components/work_item_detail_modal.vue

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export default {
139139
size="lg"
140140
modal-id="work-item-detail-modal"
141141
header-class="gl-p-0 gl-pb-2!"
142+
scrollable
142143
@hide="closeModal"
143144
>
144145
<gl-alert v-if="error" variant="danger" @dismiss="error = false">

0 commit comments

Comments
 (0)