Skip to content

Commit f8d256d

Browse files
author
GitLab Bot
committed
Add latest changes from gitlab-org/gitlab@master
1 parent 190e96d commit f8d256d

File tree

42 files changed

+907
-546
lines changed

Some content is hidden

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

42 files changed

+907
-546
lines changed

app/assets/javascripts/ci/common/private/job_name_component.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default {
3737
:use-link="false"
3838
class="gl-leading-0"
3939
/>
40-
<span class="mw-70p gl-inline-block gl-truncate gl-pl-3" :title="name">
40+
<span class="gl-inline-block gl-max-w-7/10 gl-truncate gl-pl-3" :title="name">
4141
{{ name }}
4242
</span>
4343
</span>

app/assets/javascripts/issues/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,12 @@ export function initShow() {
4949
import(/* webpackChunkName: 'design_management' */ '~/design_management')
5050
.then((module) => module.default())
5151
.catch(() => {});
52+
53+
if (gon.features.workItemsViewPreference) {
54+
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
55+
.then(({ initWorkItemsFeedback }) => {
56+
initWorkItemsFeedback();
57+
})
58+
.catch({});
59+
}
5260
}

app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export default {
116116
return this.tag.layers ? n__('%d layer', '%d layers', this.tag.layers) : '';
117117
},
118118
mobileClasses() {
119-
return this.isMobile ? 'mw-s' : '';
119+
return this.isMobile ? 'gl-max-w-20' : '';
120120
},
121121
shortDigest() {
122122
// remove sha256: from the string, and show only the first 7 char
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
import { initWorkItemsRoot } from '~/work_items';
22

33
initWorkItemsRoot();
4+
5+
if (gon.features.work_items_view_preference) {
6+
import('~/work_items_feedback')
7+
.then(({ initWorkItemsFeedback }) => {
8+
initWorkItemsFeedback();
9+
})
10+
.catch({});
11+
}

app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export default {
198198
v-show="dragging && !enableDragBehavior"
199199
class="card upload-dropzone-border upload-dropzone-overlay gl-absolute gl-flex gl-h-full gl-w-full gl-items-center gl-justify-center gl-p-4"
200200
>
201-
<div v-show="!isDragDataValid" class="mw-50 gl-text-center">
201+
<div v-show="!isDragDataValid" class="gl-max-w-1/2 gl-text-center">
202202
<slot name="invalid-drag-data-slot">
203203
<h3 :class="{ 'gl-inline gl-text-base': !displayAsCard }">
204204
{{ __('Oh no!') }}
@@ -210,7 +210,7 @@ export default {
210210
}}</span>
211211
</slot>
212212
</div>
213-
<div v-show="isDragDataValid" class="mw-50 gl-text-center">
213+
<div v-show="isDragDataValid" class="gl-max-w-1/2 gl-text-center">
214214
<slot name="valid-drag-data-slot">
215215
<h3 :class="{ 'gl-inline gl-text-base': !displayAsCard }">
216216
{{ __('Incoming!') }}

app/assets/javascripts/work_items/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ export const initWorkItemsRoot = ({ workItemType, workspaceType } = {}) => {
8181
},
8282
});
8383

84+
if (gon.features.workItemsViewPreference) {
85+
import(/* webpackChunkName: 'work_items_feedback' */ '~/work_items_feedback')
86+
.then(({ initWorkItemsFeedback }) => {
87+
initWorkItemsFeedback();
88+
})
89+
.catch({});
90+
}
91+
8492
return new Vue({
8593
el,
8694
name: 'WorkItemsRoot',

app/assets/javascripts/work_items/router/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ Vue.use(VueRouter);
1010

1111
export function createRouter({
1212
fullPath,
13-
workItemType = 'work_items',
1413
workspaceType = WORKSPACE_PROJECT,
1514
defaultBranch,
1615
isGroup,
@@ -24,6 +23,6 @@ export function createRouter({
2423
return new VueRouter({
2524
routes: routes(isGroup),
2625
mode: 'history',
27-
base: joinPaths(gon?.relative_url_root, workspacePath, fullPath, '-', workItemType),
26+
base: joinPaths(gon?.relative_url_root, workspacePath, fullPath, '-'),
2827
});
2928
}

app/assets/javascripts/work_items/router/routes.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ROUTES } from '../constants';
55
function getRoutes(isGroup) {
66
const routes = [
77
{
8-
path: '/:iid',
8+
path: '/:type(issues|epics|work_items)/:iid',
99
name: ROUTES.workItem,
1010
component: () => import('../pages/work_item_root.vue'),
1111
props: true,
@@ -27,15 +27,15 @@ function getRoutes(isGroup) {
2727

2828
if (isGroup) {
2929
routes.unshift({
30-
path: '/',
30+
path: '/:type(issues|epics|work_items)',
3131
name: ROUTES.index,
3232
component: WorkItemList,
3333
});
3434
}
3535

3636
if (gon.features?.workItemsAlpha) {
3737
routes.unshift({
38-
path: '/new',
38+
path: '/:type(issues|epics|work_items)/new',
3939
name: ROUTES.new,
4040
component: () => import('../pages/create_work_item.vue'),
4141
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<script>
2+
import { GlBadge, GlPopover, GlLink, GlToggle } from '@gitlab/ui';
3+
import { uniqueId } from 'lodash';
4+
import { createAlert } from '~/alert';
5+
import { __ } from '~/locale';
6+
import * as Sentry from '~/sentry/sentry_browser_wrapper';
7+
import getUserPreferences from '../graphql/user_preferences.query.graphql';
8+
import setUseWorkItemsView from '../graphql/set_use_work_items_view.mutation.graphql';
9+
10+
export default {
11+
name: 'WorkItemToggle',
12+
components: {
13+
GlBadge,
14+
GlPopover,
15+
GlLink,
16+
GlToggle,
17+
},
18+
data() {
19+
return {
20+
currentUser: {
21+
userPreferences: {},
22+
},
23+
feedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/463598',
24+
};
25+
},
26+
apollo: {
27+
currentUser: {
28+
query: getUserPreferences,
29+
},
30+
},
31+
computed: {
32+
onOff() {
33+
return this.currentUser.userPreferences.useWorkItemsView ? __('On') : __('Off');
34+
},
35+
},
36+
methods: {
37+
setWorkItemsView(val) {
38+
this.$apollo
39+
.mutate({
40+
mutation: setUseWorkItemsView,
41+
variables: {
42+
useWorkItemsView: val,
43+
},
44+
update: (cache, { data: { userPreferencesUpdate } }) => {
45+
cache.modify({
46+
id: cache.identify(this.currentUser),
47+
fields: {
48+
userPreferences(existingPreferences = {}) {
49+
return {
50+
...existingPreferences,
51+
...userPreferencesUpdate.userPreferences,
52+
};
53+
},
54+
},
55+
});
56+
57+
window.location.reload();
58+
},
59+
})
60+
.catch((error) => {
61+
createAlert({
62+
message: __('Something went wrong. Please try again.'),
63+
});
64+
Sentry.captureException(error);
65+
});
66+
},
67+
},
68+
badgeId: uniqueId(),
69+
i18n: {
70+
previewWorkItems: __(
71+
'Preview the new issues experience, with real time updates and refreshed design. Some features are not yet supported, see feedback issue for details.',
72+
),
73+
leaveFeedback: __('Leave feedback'),
74+
newIssueLook: __('New issue look'),
75+
},
76+
};
77+
</script>
78+
79+
<template>
80+
<div class="gl-flex gl-content-center">
81+
<gl-badge :id="$options.badgeId" variant="info" icon="information-o" href="#"
82+
>{{ $options.i18n.newIssueLook }}: {{ onOff }}</gl-badge
83+
>
84+
<gl-popover
85+
:target="$options.badgeId"
86+
data-testid="work-item-feedback-popover"
87+
triggers="focus click manual blur"
88+
placement="bottom"
89+
show-close-button
90+
:title="$options.i18n.newIssueLook"
91+
>
92+
<gl-toggle
93+
:value="currentUser.userPreferences.useWorkItemsView"
94+
:label="onOff"
95+
label-position="left"
96+
@change="setWorkItemsView"
97+
/>
98+
<div class="gl-pt-2">
99+
{{ $options.i18n.previewWorkItems }}
100+
</div>
101+
<gl-link target="_blank" :href="feedbackIssue">{{ $options.i18n.leaveFeedback }}</gl-link>
102+
</gl-popover>
103+
</div>
104+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mutation setUseWorkItemsView($useWorkItemsView: Boolean) {
2+
userPreferencesUpdate(input: { useWorkItemsView: $useWorkItemsView }) {
3+
userPreferences {
4+
useWorkItemsView
5+
}
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
query getUserPreferences {
2+
currentUser {
3+
id
4+
userPreferences {
5+
useWorkItemsView
6+
}
7+
}
8+
}

app/assets/javascripts/work_items_feedback/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Vue from 'vue';
22
import VueApollo from 'vue-apollo';
33
import { apolloProvider } from '~/graphql_shared/issuable_client';
44
import WorkItemFeedback from './components/work_item_feedback.vue';
5+
import WorkItemViewToggle from './components/work_item_view_toggle.vue';
56

67
Vue.use(VueApollo);
78

@@ -12,7 +13,7 @@ export const initWorkItemsFeedback = ({
1213
content,
1314
expiry,
1415
featureName,
15-
}) => {
16+
} = {}) => {
1617
if (expiry) {
1718
const expiryDate = new Date(expiry);
1819
if (Date.now() > expiryDate) {
@@ -34,7 +35,7 @@ export const initWorkItemsFeedback = ({
3435
featureName,
3536
},
3637
render(h) {
37-
return h(WorkItemFeedback);
38+
return h(feedbackIssue ? WorkItemFeedback : WorkItemViewToggle);
3839
},
3940
});
4041
};

app/assets/stylesheets/framework/common.scss

-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ li.note {
364364
.h-32-px { height: 32px;}
365365

366366
.mw-6em { max-width: 6em; }
367-
.mw-70p { max-width: 70%; }
368367

369368
// By default flex items don't shrink below their minimum content size.
370369
// To change this, these clases set a min-width or min-height

app/controllers/projects/issues_controller.rb

+14
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class Projects::IssuesController < Projects::ApplicationController
6767
push_force_frontend_feature_flag(:work_items_alpha, project&.work_items_alpha_feature_flag_enabled?)
6868
push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
6969
push_frontend_feature_flag(:namespace_level_work_items, project&.group)
70+
push_frontend_feature_flag(:work_items_view_preference, current_user)
7071
end
7172

7273
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
@@ -140,6 +141,15 @@ def new
140141
respond_with(@issue)
141142
end
142143

144+
def show
145+
return super unless show_work_item? && request.format.html?
146+
147+
@right_sidebar = false
148+
@work_item = issue.becomes(::WorkItem) # rubocop:disable Cop/AvoidBecomes -- We need the instance to be a work item
149+
150+
render 'projects/work_items/show'
151+
end
152+
143153
def edit
144154
respond_with(@issue)
145155
end
@@ -390,6 +400,10 @@ def disable_query_limiting
390400

391401
private
392402

403+
def show_work_item?
404+
Feature.enabled?(:work_items_view_preference, current_user) && current_user&.user_preference&.use_work_items_view
405+
end
406+
393407
def work_item_redirect_except_actions
394408
ISSUES_EXCEPT_ACTIONS
395409
end

app/models/bulk_import.rb

+4-16
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class BulkImport < ApplicationRecord
5555
# rubocop:disable Style/SymbolProc
5656
after_transition any => [:finished, :failed, :timeout] do |bulk_import|
5757
bulk_import.update_has_failures
58-
bulk_import.notify_owners_of_completion
58+
bulk_import.send_completion_notification
5959
end
6060
# rubocop:enable Style/SymbolProc
6161

@@ -103,24 +103,12 @@ def completed?
103103
finished? || failed? || timeout? || canceled?
104104
end
105105

106-
def notify_owners_of_completion
107-
users_to_notify = parent_group_entity&.group&.owners
108-
109-
return if users_to_notify.blank?
110-
111-
users_to_notify.each do |owner|
112-
run_after_commit do
113-
Notify.bulk_import_complete(owner.id, id).deliver_later
114-
end
106+
def send_completion_notification
107+
run_after_commit do
108+
Notify.bulk_import_complete(user.id, id).deliver_later
115109
end
116110
end
117111

118-
# Finds the root group entity of the BulkImport's entity tree.
119-
# @return [BulkImports::Entity, nil]
120-
def parent_group_entity
121-
entities.group_entity.where(parent: nil).first
122-
end
123-
124112
def destination_group_roots
125113
entities.where(parent: nil).filter_map do |entity|
126114
entity.group || entity.project

app/workers/process_commit_worker.rb

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def issues_to_close(project, commit, user)
6767
Gitlab::ClosingIssueExtractor
6868
.new(project, user)
6969
.closed_by_message(commit.safe_message)
70+
.reject { |issue| issue.is_a?(Issue) && !issue.autoclose_by_merged_closing_merge_request? }
7071
end
7172

7273
def update_issue_metrics(commit, author)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
name: work_items_view_preference
3+
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/461855
4+
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165085
5+
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/482931
6+
milestone: '17.4'
7+
group: group::project management
8+
type: beta
9+
default_enabled: false

doc/administration/backup_restore/restore_gitlab.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,4 @@ To resolve this, you can update the Git [server hooks](../server_hooks.md) for G
504504
### Successful restore with repositories showing as empty when using `fapolicyd`
505505

506506
When using `fapolicyd` for increased security, GitLab can report that a restore was successful but repositories show as empty. For more troubleshooting help, see
507-
[Gitaly Troubleshooting documentation](../../administration/gitaly/troubleshooting.md#repositories-are-shown-as-empty-after-a-gitlab-restore).
507+
[Gitaly Troubleshooting documentation](../gitaly/troubleshooting.md#repositories-are-shown-as-empty-after-a-gitlab-restore).

0 commit comments

Comments
 (0)