diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 49420e8c346..fd5fa34f296 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-d62dac6422b1a1e4198a14b7b4e831633e85a79a
+8fa071ac4eb77db878e85ce1fa6bb7bbad18e963
diff --git a/app/assets/javascripts/access_tokens/components/new_access_token_app.vue b/app/assets/javascripts/access_tokens/components/new_access_token_app.vue
index d705b9a11ba..8d9a01c2a4d 100644
--- a/app/assets/javascripts/access_tokens/components/new_access_token_app.vue
+++ b/app/assets/javascripts/access_tokens/components/new_access_token_app.vue
@@ -102,7 +102,7 @@ export default {
onSuccess(event) {
this.beforeDisplayResults();
- const [{ newToken }] = convertEventDetail(event);
+ const [{ newToken, total }] = convertEventDetail(event);
this.newToken = newToken;
this.alert = createAlert({ message: this.alertInfoMessage, variant: VARIANT_INFO });
@@ -124,8 +124,7 @@ export default {
document.querySelectorAll('.js-token-card').forEach((el) => {
el.querySelector('.js-add-new-token-form').style.display = '';
el.querySelector('.js-toggle-button').style.display = 'block';
- el.querySelector('.js-token-count').innerText =
- parseInt(el.querySelector('.js-token-count').innerText, 10) + 1;
+ el.querySelector('.js-token-count').innerText = total;
});
},
},
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 175fc166768..f4c79bd97bd 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -187,7 +187,7 @@ export function getActionFromHref(pathName) {
export const pageBundles = {
show: () => import(/* webpackPrefetch: true */ '~/mr_notes/mount_app'),
diffs: () => import(/* webpackPrefetch: true */ '~/diffs'),
- reports: () => import('ee_else_ce/merge_requests/reports'),
+ reports: () => import('~/merge_requests/reports'),
};
export default class MergeRequestTabs {
diff --git a/app/assets/javascripts/merge_requests/reports/components/app.vue b/app/assets/javascripts/merge_requests/reports/components/app.vue
new file mode 100644
index 00000000000..f66470dc63b
--- /dev/null
+++ b/app/assets/javascripts/merge_requests/reports/components/app.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
{{ s__('MrReports|Reports') }}
+
+
+
+
diff --git a/app/assets/javascripts/merge_requests/reports/constants.js b/app/assets/javascripts/merge_requests/reports/constants.js
new file mode 100644
index 00000000000..4cd134372c5
--- /dev/null
+++ b/app/assets/javascripts/merge_requests/reports/constants.js
@@ -0,0 +1,4 @@
+export const BLOCKERS_ROUTE = 'index';
+export const CODE_QUALITY_ROUTE = 'code-quality';
+export const SECURITY_ROUTE = 'security';
+export const LICENSE_COMPLIANCE_ROUTE = 'license-compliance';
diff --git a/app/assets/javascripts/merge_requests/reports/index.js b/app/assets/javascripts/merge_requests/reports/index.js
index 2d1ec238274..32b1e797b2b 100644
--- a/app/assets/javascripts/merge_requests/reports/index.js
+++ b/app/assets/javascripts/merge_requests/reports/index.js
@@ -1 +1,36 @@
-export default () => {};
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import routes from './routes';
+import MergeRequestReportsApp from './components/app.vue';
+
+export default () => {
+ Vue.use(VueRouter);
+ Vue.use(VueApollo);
+
+ const el = document.getElementById('js-reports-tab');
+ const { projectPath, iid, basePath } = el.dataset;
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+ const router = new VueRouter({
+ base: basePath,
+ mode: 'history',
+ routes,
+ });
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ router,
+ apolloProvider,
+ provide: {
+ projectPath,
+ iid,
+ },
+ render(createElement) {
+ return createElement(MergeRequestReportsApp);
+ },
+ });
+};
diff --git a/app/assets/javascripts/merge_requests/reports/pages/blockers_page.vue b/app/assets/javascripts/merge_requests/reports/pages/blockers_page.vue
new file mode 100644
index 00000000000..c3bf0782a5b
--- /dev/null
+++ b/app/assets/javascripts/merge_requests/reports/pages/blockers_page.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/app/assets/javascripts/merge_requests/reports/pages/index.vue b/app/assets/javascripts/merge_requests/reports/pages/index.vue
new file mode 100644
index 00000000000..b4f055da191
--- /dev/null
+++ b/app/assets/javascripts/merge_requests/reports/pages/index.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/app/assets/javascripts/merge_requests/reports/routes.js b/app/assets/javascripts/merge_requests/reports/routes.js
new file mode 100644
index 00000000000..a3906ffbd03
--- /dev/null
+++ b/app/assets/javascripts/merge_requests/reports/routes.js
@@ -0,0 +1,31 @@
+import BlockersPage from 'ee_else_ce/merge_requests/reports/pages/blockers_page.vue';
+import IndexComponent from './pages/index.vue';
+import {
+ BLOCKERS_ROUTE,
+ CODE_QUALITY_ROUTE,
+ LICENSE_COMPLIANCE_ROUTE,
+ SECURITY_ROUTE,
+} from './constants';
+
+export default [
+ {
+ path: '/',
+ name: BLOCKERS_ROUTE,
+ component: BlockersPage,
+ },
+ {
+ path: '/?type=code-quality',
+ name: CODE_QUALITY_ROUTE,
+ component: IndexComponent,
+ },
+ {
+ path: '/?type=security',
+ name: SECURITY_ROUTE,
+ component: IndexComponent,
+ },
+ {
+ path: '/?type=license-compliance',
+ name: LICENSE_COMPLIANCE_ROUTE,
+ component: IndexComponent,
+ },
+];
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index ff799809e88..ee396cb730f 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -229,7 +229,6 @@ const initTreeHistoryLinkApp = (el) => {
{
attrs: {
href: url.href,
- class: '!gl-ml-3',
},
},
[__('History')],
diff --git a/app/assets/javascripts/pages/projects/merge_requests/reports/index.js b/app/assets/javascripts/pages/projects/merge_requests/reports/index.js
new file mode 100644
index 00000000000..efd5c7ccba9
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/merge_requests/reports/index.js
@@ -0,0 +1,5 @@
+import { initMrPage } from '~/pages/projects/merge_requests/page';
+import initReportsApp from '~/merge_requests/reports';
+
+initMrPage();
+initReportsApp();
diff --git a/app/assets/javascripts/projects/tree/components/commit_pipeline_status.vue b/app/assets/javascripts/projects/tree/components/commit_pipeline_status.vue
index d7c38875d86..7d376cf143c 100644
--- a/app/assets/javascripts/projects/tree/components/commit_pipeline_status.vue
+++ b/app/assets/javascripts/projects/tree/components/commit_pipeline_status.vue
@@ -99,13 +99,11 @@ export default {
};
-
-
-
-
+
+
diff --git a/app/assets/javascripts/search/results/constants.js b/app/assets/javascripts/search/results/constants.js
index 23f13e9ad72..a023079a435 100644
--- a/app/assets/javascripts/search/results/constants.js
+++ b/app/assets/javascripts/search/results/constants.js
@@ -1,4 +1,4 @@
-export const DEFAULT_FETCH_CHUNKS = 50;
+export const DEFAULT_FETCH_CHUNKS = 5;
export const PROJECT_GRAPHQL_ID_TYPE = 'Project';
export const GROUP_GRAPHQL_ID_TYPE = 'Group';
export const SEARCH_RESULTS_DEBOUNCE = 500;
diff --git a/app/assets/javascripts/todos/components/queries/todo.fragment.graphql b/app/assets/javascripts/todos/components/queries/todo.fragment.graphql
index f2f3149aa9a..6aa0eceb358 100644
--- a/app/assets/javascripts/todos/components/queries/todo.fragment.graphql
+++ b/app/assets/javascripts/todos/components/queries/todo.fragment.graphql
@@ -29,6 +29,7 @@ fragment Todo on Todo {
... on Design {
issue {
id
+ name
reference
}
}
diff --git a/app/assets/javascripts/todos/components/todo_item_title.vue b/app/assets/javascripts/todos/components/todo_item_title.vue
index 0cebbcfd141..a2b1d2a4601 100644
--- a/app/assets/javascripts/todos/components/todo_item_title.vue
+++ b/app/assets/javascripts/todos/components/todo_item_title.vue
@@ -34,6 +34,9 @@ export default {
isAlert() {
return this.todo.targetType === TODO_TARGET_TYPE_ALERT;
},
+ isDesign() {
+ return this.todo.targetType === TODO_TARGET_TYPE_DESIGN;
+ },
isMemberAccessRequestAction() {
return this.todo.action === TODO_ACTION_TYPE_MEMBER_ACCESS_REQUESTED;
},
@@ -72,19 +75,49 @@ export default {
(this.isMergeRequest || this.isIssue || this.isAlert) && this.issuableState !== STATUS_OPEN
);
},
- targetTitle() {
+ /**
+ * Full title line of the todo title + full reference, joined by a middot
+ */
+ todoTitle() {
+ return [this.targetName, this.targetFullReference].filter(Boolean).join(' · ');
+ },
+ /**
+ * Right half of a todo title: Full reference to the todo (parentPath + Target Reference)
+ */
+ targetFullReference() {
+ return [this.parentPath, this.targetReference].filter(Boolean).join(' ');
+ },
+ /**
+ * Left half of a To-Do title, often the entity name
+ */
+ targetName() {
if (this.isMemberAccessRequestAction) {
return '';
}
- return this.todo.targetEntity?.name ?? '';
+ const name = this.todo.targetEntity?.name ?? '';
+
+ if (this.isDesign && this.todo.targetEntity?.issue?.name) {
+ if (name) {
+ return `${this.todo.targetEntity.issue.name} › ${name}`;
+ }
+ return this.todo.targetEntity.issue.name;
+ }
+
+ return name;
},
+ /**
+ * Reference of the target entity
+ */
targetReference() {
- if (this.todo.targetEntity?.issue?.reference) {
+ if (this.isDesign && this.todo.targetEntity?.issue?.reference) {
return this.todo.targetEntity.issue.reference;
}
return this.todo.targetEntity?.reference ?? '';
},
+ /**
+ * Parent path of the target entity Reference of the target entity
+ */
parentPath() {
if (this.todo.group) {
return this.todo.group.fullName;
@@ -96,21 +129,6 @@ export default {
return '';
},
- showSeparator() {
- if (!this.targetTitle) {
- return false;
- }
-
- if (this.parentPath) {
- return true;
- }
-
- if (this.targetReference) {
- return true;
- }
-
- return false;
- },
icon() {
switch (this.todo.targetType) {
case TODO_TARGET_TYPE_ISSUE:
@@ -122,7 +140,7 @@ export default {
case TODO_TARGET_TYPE_ALERT:
return 'status-alert';
case TODO_TARGET_TYPE_DESIGN:
- return 'issues';
+ return 'media';
case TODO_TARGET_TYPE_SSH_KEY:
return 'token';
case TODO_TARGET_TYPE_EPIC:
@@ -140,10 +158,7 @@ export default {
- {{ targetTitle }}
- ·
- {{ parentPath }}
- {{ targetReference }}
+ {{ todoTitle }}
diff --git a/app/assets/javascripts/todos/components/todo_item_title_hidden_by_saml.vue b/app/assets/javascripts/todos/components/todo_item_title_hidden_by_saml.vue
index 2eaa94c99cd..1a6e35a73ad 100644
--- a/app/assets/javascripts/todos/components/todo_item_title_hidden_by_saml.vue
+++ b/app/assets/javascripts/todos/components/todo_item_title_hidden_by_saml.vue
@@ -25,7 +25,7 @@ export default {
{{ $options.i18n.hiddenTodoBadgeText }}
- {{ $options.i18n.hiddenTodoTitle }}
+ {{ $options.i18n.hiddenTodoTitle }}
diff --git a/app/assets/javascripts/vue_shared/components/list_selector/group_item.vue b/app/assets/javascripts/vue_shared/components/list_selector/group_item.vue
index 1344174cad4..a9d72356882 100644
--- a/app/assets/javascripts/vue_shared/components/list_selector/group_item.vue
+++ b/app/assets/javascripts/vue_shared/components/list_selector/group_item.vue
@@ -1,11 +1,11 @@