Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 12:09:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 12:09:36 +0300
commitf9fe7cda4bdbc477d8d76e5def4023f7d03bab46 (patch)
tree293285f6f438a22e7beb35ef8cf5e1ffae131094 /app
parenta2f16969fa9bb982d5ec01f18efff5eabfc89a67 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/components/board_assignee_dropdown.vue2
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue4
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue2
-rw-r--r--app/assets/javascripts/boards/graphql/board.fragment.graphql (renamed from app/assets/javascripts/boards/queries/board.fragment.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board.mutation.graphql (renamed from app/assets/javascripts/boards/queries/board.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_labels.query.graphql (renamed from app/assets/javascripts/boards/queries/board_labels.query.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_list.fragment.graphql (renamed from app/assets/javascripts/boards/queries/board_list.fragment.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_list_create.mutation.graphql (renamed from app/assets/javascripts/boards/queries/board_list_create.mutation.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/board_list_destroy.mutation.graphql (renamed from app/assets/javascripts/boards/queries/board_list_destroy.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_list_shared.fragment.graphql (renamed from app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_list_update.mutation.graphql (renamed from app/assets/javascripts/boards/queries/board_list_update.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/board_lists.query.graphql (renamed from app/assets/javascripts/boards/queries/board_lists.query.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/group_boards.query.graphql (renamed from app/assets/javascripts/boards/queries/group_boards.query.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/group_milestones.query.graphql (renamed from app/assets/javascripts/boards/queries/group_milestones.query.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/issue.fragment.graphql (renamed from app/assets/javascripts/boards/queries/issue.fragment.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/issue_create.mutation.graphql (renamed from app/assets/javascripts/boards/queries/issue_create.mutation.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql (renamed from app/assets/javascripts/boards/queries/issue_move_list.mutation.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/issue_set_due_date.mutation.graphql (renamed from app/assets/javascripts/boards/queries/issue_set_due_date.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/issue_set_labels.mutation.graphql (renamed from app/assets/javascripts/boards/queries/issue_set_labels.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/issue_set_milestone.mutation.graphql (renamed from app/assets/javascripts/boards/queries/issue_set_milestone.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/issue_set_subscription.mutation.graphql (renamed from app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql)0
-rw-r--r--app/assets/javascripts/boards/graphql/lists_issues.query.graphql (renamed from app/assets/javascripts/boards/queries/lists_issues.query.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/project_boards.query.graphql (renamed from app/assets/javascripts/boards/queries/project_boards.query.graphql)2
-rw-r--r--app/assets/javascripts/boards/graphql/users_search.query.graphql (renamed from app/assets/javascripts/boards/queries/users_search.query.graphql)0
-rw-r--r--app/assets/javascripts/boards/stores/actions.js34
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js2
-rw-r--r--app/assets/javascripts/boards/stores/getters.js1
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue2
-rw-r--r--app/assets/javascripts/diffs/store/actions.js2
-rw-r--r--app/assets/javascripts/diffs/store/utils.js2
-rw-r--r--app/assets/javascripts/diffs/utils/diff_file.js (renamed from app/assets/javascripts/diffs/diff_file.js)2
-rw-r--r--app/assets/javascripts/incidents_settings/components/alerts_form.vue4
-rw-r--r--app/assets/javascripts/incidents_settings/components/pagerduty_form.vue31
-rw-r--r--app/assets/javascripts/incidents_settings/constants.js16
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue5
-rw-r--r--app/assets/javascripts/notes/components/diff_with_note.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue2
-rw-r--r--app/assets/javascripts/whats_new/components/app.vue130
-rw-r--r--app/assets/javascripts/whats_new/components/feature.vue64
-rw-r--r--app/assets/javascripts/whats_new/index.js8
-rw-r--r--app/assets/javascripts/whats_new/store/actions.js3
-rw-r--r--app/assets/stylesheets/components/whats_new.scss26
-rw-r--r--app/assets/stylesheets/page_bundles/oncall_schedules.scss112
-rw-r--r--app/controllers/whats_new_controller.rb27
-rw-r--r--app/helpers/whats_new_helper.rb6
-rw-r--r--app/models/release_highlight.rb38
-rw-r--r--app/models/service.rb3
-rw-r--r--app/services/groups/transfer_service.rb13
-rw-r--r--app/services/projects/transfer_service.rb11
-rw-r--r--app/views/layouts/header/_default.html.haml2
51 files changed, 415 insertions, 157 deletions
diff --git a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
index b4a9d34e738..76b468a3402 100644
--- a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
+++ b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue
@@ -14,7 +14,7 @@ import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import MultiSelectDropdown from '~/vue_shared/components/sidebar/multiselect_dropdown.vue';
import getIssueParticipants from '~/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql';
-import searchUsers from '~/boards/queries/users_search.query.graphql';
+import searchUsers from '~/boards/graphql/users_search.query.graphql';
export default {
noSearchDelay: 0,
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index 2daec46e64b..435ea3f8b7a 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -12,8 +12,8 @@ import {
import httpStatusCodes from '~/lib/utils/http_status';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import projectQuery from '../queries/project_boards.query.graphql';
-import groupQuery from '../queries/group_boards.query.graphql';
+import projectQuery from '../graphql/project_boards.query.graphql';
+import groupQuery from '../graphql/group_boards.query.graphql';
import boardsStore from '../stores/boards_store';
import BoardForm from './board_form.vue';
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
index f7b7fd3f61f..78c3f8acc62 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
@@ -10,7 +10,7 @@ import {
} from '@gitlab/ui';
import { fetchPolicies } from '~/lib/graphql';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
-import groupMilestones from '../../queries/group_milestones.query.graphql';
+import groupMilestones from '../../graphql/group_milestones.query.graphql';
import createFlash from '~/flash';
import { __, s__ } from '~/locale';
diff --git a/app/assets/javascripts/boards/queries/board.fragment.graphql b/app/assets/javascripts/boards/graphql/board.fragment.graphql
index 872a4c4afbc..872a4c4afbc 100644
--- a/app/assets/javascripts/boards/queries/board.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/board.fragment.graphql
diff --git a/app/assets/javascripts/boards/queries/board.mutation.graphql b/app/assets/javascripts/boards/graphql/board.mutation.graphql
index ef2b81a7939..ef2b81a7939 100644
--- a/app/assets/javascripts/boards/queries/board.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/board.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/board_labels.query.graphql b/app/assets/javascripts/boards/graphql/board_labels.query.graphql
index 42a94419a97..42a94419a97 100644
--- a/app/assets/javascripts/boards/queries/board_labels.query.graphql
+++ b/app/assets/javascripts/boards/graphql/board_labels.query.graphql
diff --git a/app/assets/javascripts/boards/queries/board_list.fragment.graphql b/app/assets/javascripts/boards/graphql/board_list.fragment.graphql
index bbf3314377e..bbf3314377e 100644
--- a/app/assets/javascripts/boards/queries/board_list.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/board_list.fragment.graphql
diff --git a/app/assets/javascripts/boards/queries/board_list_create.mutation.graphql b/app/assets/javascripts/boards/graphql/board_list_create.mutation.graphql
index 48420b349ae..f78a21baa7f 100644
--- a/app/assets/javascripts/boards/queries/board_list_create.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/board_list_create.mutation.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/board_list.fragment.graphql"
+#import "ee_else_ce/boards/graphql/board_list.fragment.graphql"
mutation CreateBoardList(
$boardId: BoardID!
diff --git a/app/assets/javascripts/boards/queries/board_list_destroy.mutation.graphql b/app/assets/javascripts/boards/graphql/board_list_destroy.mutation.graphql
index ef3fd36e980..ef3fd36e980 100644
--- a/app/assets/javascripts/boards/queries/board_list_destroy.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/board_list_destroy.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql b/app/assets/javascripts/boards/graphql/board_list_shared.fragment.graphql
index d85b736720b..d85b736720b 100644
--- a/app/assets/javascripts/boards/queries/board_list_shared.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/board_list_shared.fragment.graphql
diff --git a/app/assets/javascripts/boards/queries/board_list_update.mutation.graphql b/app/assets/javascripts/boards/graphql/board_list_update.mutation.graphql
index b474c9acb93..b474c9acb93 100644
--- a/app/assets/javascripts/boards/queries/board_list_update.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/board_list_update.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/board_lists.query.graphql b/app/assets/javascripts/boards/graphql/board_lists.query.graphql
index 88425e9a9c1..eb922f162f8 100644
--- a/app/assets/javascripts/boards/queries/board_lists.query.graphql
+++ b/app/assets/javascripts/boards/graphql/board_lists.query.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/board_list.fragment.graphql"
+#import "ee_else_ce/boards/graphql/board_list.fragment.graphql"
query ListIssues(
$fullPath: ID!
diff --git a/app/assets/javascripts/boards/queries/group_boards.query.graphql b/app/assets/javascripts/boards/graphql/group_boards.query.graphql
index 74c224add7d..feafd6ae10d 100644
--- a/app/assets/javascripts/boards/queries/group_boards.query.graphql
+++ b/app/assets/javascripts/boards/graphql/group_boards.query.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/board.fragment.graphql"
+#import "ee_else_ce/boards/graphql/board.fragment.graphql"
query group_boards($fullPath: ID!) {
group(fullPath: $fullPath) {
diff --git a/app/assets/javascripts/boards/queries/group_milestones.query.graphql b/app/assets/javascripts/boards/graphql/group_milestones.query.graphql
index f2ab12ef4a7..f2ab12ef4a7 100644
--- a/app/assets/javascripts/boards/queries/group_milestones.query.graphql
+++ b/app/assets/javascripts/boards/graphql/group_milestones.query.graphql
diff --git a/app/assets/javascripts/boards/queries/issue.fragment.graphql b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
index 1395bef39ed..1395bef39ed 100644
--- a/app/assets/javascripts/boards/queries/issue.fragment.graphql
+++ b/app/assets/javascripts/boards/graphql/issue.fragment.graphql
diff --git a/app/assets/javascripts/boards/queries/issue_create.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql
index 65be147be07..c1a2361a4e8 100644
--- a/app/assets/javascripts/boards/queries/issue_create.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_create.mutation.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/issue.fragment.graphql"
+#import "ee_else_ce/boards/graphql/issue.fragment.graphql"
mutation CreateIssue($input: CreateIssueInput!) {
createIssue(input: $input) {
diff --git a/app/assets/javascripts/boards/queries/issue_move_list.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql
index ff6aa597f48..3c574fd8c87 100644
--- a/app/assets/javascripts/boards/queries/issue_move_list.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_move_list.mutation.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/issue.fragment.graphql"
+#import "ee_else_ce/boards/graphql/issue.fragment.graphql"
mutation IssueMoveList(
$projectPath: ID!
diff --git a/app/assets/javascripts/boards/queries/issue_set_due_date.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_set_due_date.mutation.graphql
index bbea248cf85..bbea248cf85 100644
--- a/app/assets/javascripts/boards/queries/issue_set_due_date.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_set_due_date.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/issue_set_labels.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_set_labels.mutation.graphql
index 3c5f4b3e3bd..3c5f4b3e3bd 100644
--- a/app/assets/javascripts/boards/queries/issue_set_labels.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_set_labels.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/issue_set_milestone.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_set_milestone.mutation.graphql
index 5dc78a03a06..5dc78a03a06 100644
--- a/app/assets/javascripts/boards/queries/issue_set_milestone.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_set_milestone.mutation.graphql
diff --git a/app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql b/app/assets/javascripts/boards/graphql/issue_set_subscription.mutation.graphql
index 1f383245ac2..1f383245ac2 100644
--- a/app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql
+++ b/app/assets/javascripts/boards/graphql/issue_set_subscription.mutation.graphql
diff --git a/app/assets/javascripts/boards/queries/lists_issues.query.graphql b/app/assets/javascripts/boards/graphql/lists_issues.query.graphql
index 5dbfe4675c6..43af7d2b2f1 100644
--- a/app/assets/javascripts/boards/queries/lists_issues.query.graphql
+++ b/app/assets/javascripts/boards/graphql/lists_issues.query.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/issue.fragment.graphql"
+#import "ee_else_ce/boards/graphql/issue.fragment.graphql"
query ListIssues(
$fullPath: ID!
diff --git a/app/assets/javascripts/boards/queries/project_boards.query.graphql b/app/assets/javascripts/boards/graphql/project_boards.query.graphql
index a1326bd5eff..f98d25ba671 100644
--- a/app/assets/javascripts/boards/queries/project_boards.query.graphql
+++ b/app/assets/javascripts/boards/graphql/project_boards.query.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/boards/queries/board.fragment.graphql"
+#import "ee_else_ce/boards/graphql/board.fragment.graphql"
query project_boards($fullPath: ID!) {
project(fullPath: $fullPath) {
diff --git a/app/assets/javascripts/boards/queries/users_search.query.graphql b/app/assets/javascripts/boards/graphql/users_search.query.graphql
index ca016495d79..ca016495d79 100644
--- a/app/assets/javascripts/boards/queries/users_search.query.graphql
+++ b/app/assets/javascripts/boards/graphql/users_search.query.graphql
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index fd5049ef9bc..a7d8144f8af 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -1,6 +1,6 @@
import { pick } from 'lodash';
-import boardListsQuery from 'ee_else_ce/boards/queries/board_lists.query.graphql';
+import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { BoardType, ListType, inactiveId, DEFAULT_LABELS } from '~/boards/constants';
@@ -14,18 +14,18 @@ import {
} from '../boards_util';
import boardStore from '~/boards/stores/boards_store';
-import updateAssignees from '~/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql';
-import listsIssuesQuery from '../queries/lists_issues.query.graphql';
-import boardLabelsQuery from '../queries/board_labels.query.graphql';
-import createBoardListMutation from '../queries/board_list_create.mutation.graphql';
-import updateBoardListMutation from '../queries/board_list_update.mutation.graphql';
-import issueMoveListMutation from '../queries/issue_move_list.mutation.graphql';
-import destroyBoardListMutation from '../queries/board_list_destroy.mutation.graphql';
-import issueCreateMutation from '../queries/issue_create.mutation.graphql';
-import issueSetLabels from '../queries/issue_set_labels.mutation.graphql';
-import issueSetDueDate from '../queries/issue_set_due_date.mutation.graphql';
-import issueSetSubscriptionMutation from '../graphql/mutations/issue_set_subscription.mutation.graphql';
-import issueSetMilestone from '../queries/issue_set_milestone.mutation.graphql';
+import updateAssigneesMutation from '~/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql';
+import listsIssuesQuery from '../graphql/lists_issues.query.graphql';
+import boardLabelsQuery from '../graphql/board_labels.query.graphql';
+import createBoardListMutation from '../graphql/board_list_create.mutation.graphql';
+import updateBoardListMutation from '../graphql/board_list_update.mutation.graphql';
+import issueMoveListMutation from '../graphql/issue_move_list.mutation.graphql';
+import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
+import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
+import issueSetLabelsMutation from '../graphql/issue_set_labels.mutation.graphql';
+import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql';
+import issueSetSubscriptionMutation from '../graphql/issue_set_subscription.mutation.graphql';
+import issueSetMilestoneMutation from '../graphql/issue_set_milestone.mutation.graphql';
const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
@@ -324,7 +324,7 @@ export default {
return gqlClient
.mutate({
- mutation: updateAssignees,
+ mutation: updateAssigneesMutation,
variables: {
iid: getters.activeIssue.iid,
projectPath: getters.activeIssue.referencePath.split('#')[0],
@@ -350,7 +350,7 @@ export default {
setActiveIssueMilestone: async ({ commit, getters }, input) => {
const { activeIssue } = getters;
const { data } = await gqlClient.mutate({
- mutation: issueSetMilestone,
+ mutation: issueSetMilestoneMutation,
variables: {
input: {
iid: String(activeIssue.iid),
@@ -416,7 +416,7 @@ export default {
setActiveIssueLabels: async ({ commit, getters }, input) => {
const { activeIssue } = getters;
const { data } = await gqlClient.mutate({
- mutation: issueSetLabels,
+ mutation: issueSetLabelsMutation,
variables: {
input: {
iid: String(activeIssue.iid),
@@ -441,7 +441,7 @@ export default {
setActiveIssueDueDate: async ({ commit, getters }, input) => {
const { activeIssue } = getters;
const { data } = await gqlClient.mutate({
- mutation: issueSetDueDate,
+ mutation: issueSetDueDateMutation,
variables: {
input: {
iid: String(activeIssue.iid),
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 2a4bf7c7288..fa1ffdfa26a 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -22,7 +22,7 @@ import ListLabel from '../models/label';
import ListAssignee from '../models/assignee';
import ListMilestone from '../models/milestone';
-import createBoardMutation from '../queries/board.mutation.graphql';
+import createBoardMutation from '../graphql/board.mutation.graphql';
const PER_PAGE = 20;
export const gqlClient = createDefaultClient();
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index d2517fd2cfc..ca6887b6f45 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -2,7 +2,6 @@ import { find } from 'lodash';
import { inactiveId } from '../constants';
export default {
- labelToggleState: state => (state.isShowingLabels ? 'on' : 'off'),
isSidebarOpen: state => state.activeId !== inactiveId,
isSwimlanesOn: () => false,
getIssueById: state => id => {
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 32191d7e309..ed94cabe124 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -10,7 +10,7 @@ import notesEventHub from '../../notes/event_hub';
import DiffFileHeader from './diff_file_header.vue';
import DiffContent from './diff_content.vue';
import { diffViewerErrors } from '~/ide/constants';
-import { collapsedType, isCollapsed } from '../diff_file';
+import { collapsedType, isCollapsed } from '../utils/diff_file';
import {
DIFF_FILE_AUTOMATIC_COLLAPSE,
DIFF_FILE_MANUAL_COLLAPSE,
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 6dc9c71e1cd..53d1383b82e 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -19,7 +19,7 @@ import { __, s__, sprintf } from '~/locale';
import { diffViewerModes } from '~/ide/constants';
import DiffStats from './diff_stats.vue';
import { scrollToElement } from '~/lib/utils/common_utils';
-import { isCollapsed } from '../diff_file';
+import { isCollapsed } from '../utils/diff_file';
import { DIFF_FILE_HEADER } from '../i18n';
export default {
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index c41828a4221..e7f950f15c1 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -49,7 +49,7 @@ import {
DIFF_FILE_BY_FILE_COOKIE_NAME,
} from '../constants';
import { diffViewerModes } from '~/ide/constants';
-import { isCollapsed } from '../diff_file';
+import { isCollapsed } from '../utils/diff_file';
export const setBaseConfig = ({ commit }, options) => {
const {
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 8f32952676a..8949c8cd23e 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -16,7 +16,7 @@ import {
SHOW_WHITESPACE,
NO_SHOW_WHITESPACE,
} from '../constants';
-import { prepareRawDiffFile } from '../diff_file';
+import { prepareRawDiffFile } from '../utils/diff_file';
export const isAdded = line => ['new', 'new-nonewline'].includes(line.type);
export const isRemoved = line => ['old', 'old-nonewline'].includes(line.type);
diff --git a/app/assets/javascripts/diffs/diff_file.js b/app/assets/javascripts/diffs/utils/diff_file.js
index a14a30b41a9..aa801783c57 100644
--- a/app/assets/javascripts/diffs/diff_file.js
+++ b/app/assets/javascripts/diffs/utils/diff_file.js
@@ -3,7 +3,7 @@ import {
DIFF_FILE_DELETED_MODE,
DIFF_FILE_MANUAL_COLLAPSE,
DIFF_FILE_AUTOMATIC_COLLAPSE,
-} from './constants';
+} from '../constants';
function fileSymlinkInformation(file, fileList) {
const duplicates = fileList.filter(iteratedFile => iteratedFile.file_hash === file.file_hash);
diff --git a/app/assets/javascripts/incidents_settings/components/alerts_form.vue b/app/assets/javascripts/incidents_settings/components/alerts_form.vue
index 5fe0badc56e..e8daad8811e 100644
--- a/app/assets/javascripts/incidents_settings/components/alerts_form.vue
+++ b/app/assets/javascripts/incidents_settings/components/alerts_form.vue
@@ -86,7 +86,7 @@ export default {
<form ref="settingsForm" @submit.prevent="updateAlertsIntegrationSettings">
<gl-form-group class="gl-pl-0">
<gl-form-checkbox v-model="createIssueEnabled" data-qa-selector="create_issue_checkbox">
- <span>{{ $options.i18n.createIssue.label }}</span>
+ <span>{{ $options.i18n.createIncident.label }}</span>
</gl-form-checkbox>
</gl-form-group>
@@ -96,7 +96,7 @@ export default {
class="col-8 col-md-9 gl-px-6"
>
<label class="gl-display-inline-flex" for="alert-integration-settings-issue-template">
- {{ $options.i18n.issueTemplate.label }}
+ {{ $options.i18n.incidentTemplate.label }}
<gl-link :href="$options.ISSUE_TEMPLATES_DOCS_LINK" target="_blank">
<gl-icon name="question" :size="12" />
</gl-link>
diff --git a/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue b/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue
index 9a8c4bc5af9..b56dd66342a 100644
--- a/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue
+++ b/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue
@@ -109,7 +109,20 @@ export default {
{{ webhookUpdateAlertMsg }}
</gl-alert>
- <p>{{ $options.i18n.introText }}</p>
+ <p>
+ <gl-sprintf :message="$options.i18n.introText">
+ <template #link="{ content }">
+ <gl-link
+ :href="$options.CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK"
+ target="_blank"
+ class="gl-display-inline-flex"
+ >
+ <span>{{ content }}</span>
+ <gl-icon name="external-link" />
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
<form ref="settingsForm" @submit.prevent="updatePagerDutyIntegrationSettings">
<gl-form-group class="col-8 col-md-9 gl-p-0">
<gl-toggle
@@ -134,23 +147,9 @@ export default {
</template>
</gl-form-input-group>
- <div class="gl-text-gray-200 gl-pt-2">
- <gl-sprintf :message="$options.i18n.webhookUrl.helpText">
- <template #docsLink>
- <gl-link
- :href="$options.CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK"
- target="_blank"
- class="gl-display-inline-flex"
- >
- <span>{{ $options.i18n.webhookUrl.helpDocsLink }}</span>
- <gl-icon name="external-link" />
- </gl-link>
- </template>
- </gl-sprintf>
- </div>
<gl-button
v-gl-modal.resetWebhookModal
- class="gl-mt-3"
+ class="gl-mt-5"
:disabled="loading"
:loading="resettingWebhook"
data-testid="webhook-reset-btn"
diff --git a/app/assets/javascripts/incidents_settings/constants.js b/app/assets/javascripts/incidents_settings/constants.js
index 42f1f645d16..fcac9c519c2 100644
--- a/app/assets/javascripts/incidents_settings/constants.js
+++ b/app/assets/javascripts/incidents_settings/constants.js
@@ -33,17 +33,17 @@ export const I18N_ALERT_SETTINGS_FORM = {
saveBtnLabel: __('Save changes'),
introText: __('Action to take when receiving an alert. %{docsLink}'),
introLinkText: __('More information.'),
- createIssue: {
- label: __('Create an issue. Issues are created for each alert triggered.'),
+ createIncident: {
+ label: __('Create an incident. Incidents are created for each alert triggered.'),
},
- issueTemplate: {
- label: __('Issue template (optional)'),
+ incidentTemplate: {
+ label: __('Incident template (optional)'),
},
sendEmail: {
label: __('Send a separate email notification to Developers.'),
},
autoCloseIncidents: {
- label: __('Automatically close incident issues when the associated Prometheus alert resolves.'),
+ label: __('Automatically close incidents when the associated Prometheus alert resolves.'),
},
};
@@ -57,17 +57,13 @@ export const ISSUE_TEMPLATES_DOCS_LINK =
export const I18N_PAGERDUTY_SETTINGS_FORM = {
introText: s__(
- 'PagerDutySettings|Setting up a webhook with PagerDuty will automatically create a GitLab issue for each PagerDuty incident.',
+ 'PagerDutySettings|Create a GitLab incident for each PagerDuty incident by %{linkStart}configuring a webhook in PagerDuty%{linkEnd}',
),
activeToggle: {
label: s__('PagerDutySettings|Active'),
},
webhookUrl: {
label: s__('PagerDutySettings|Webhook URL'),
- helpText: s__(
- 'PagerDutySettings|Create a GitLab issue for each PagerDuty incident by %{docsLink}',
- ),
- helpDocsLink: s__('PagerDutySettings|configuring a webhook in PagerDuty'),
resetWebhookUrl: s__('PagerDutySettings|Reset webhook URL'),
copyToClipboard: __('Copy'),
updateErrMsg: s__('PagerDutySettings|Failed to update Webhook URL'),
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
index ac8a64d5f3b..c6f8ba8dcb2 100644
--- a/app/assets/javascripts/integrations/edit/components/integration_form.vue
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -59,6 +59,9 @@ export default {
showReset() {
return this.isInstanceOrGroupLevel && this.propsSource.resetPath;
},
+ saveButtonKey() {
+ return `save-button-${this.isDisabled}`;
+ },
},
methods: {
...mapActions([
@@ -117,6 +120,7 @@ export default {
<div v-if="isEditable" class="footer-block row-content-block">
<template v-if="isInstanceOrGroupLevel">
<gl-button
+ :key="saveButtonKey"
v-gl-modal.confirmSaveIntegration
category="primary"
variant="success"
@@ -130,6 +134,7 @@ export default {
</template>
<gl-button
v-else
+ :key="saveButtonKey"
category="primary"
variant="success"
type="submit"
diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue
index 98e3ae5179c..1580c94658a 100644
--- a/app/assets/javascripts/notes/components/diff_with_note.vue
+++ b/app/assets/javascripts/notes/components/diff_with_note.vue
@@ -7,7 +7,7 @@ import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
import ImageDiffOverlay from '~/diffs/components/image_diff_overlay.vue';
import { getDiffMode } from '~/diffs/store/utils';
import { diffViewerModes } from '~/ide/constants';
-import { isCollapsed } from '../../diffs/diff_file';
+import { isCollapsed } from '../../diffs/utils/diff_file';
const FIRST_CHAR_REGEX = /^(\+|-| )/;
diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
index 1785174e8d7..07abfa8d103 100644
--- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
+++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
@@ -1,7 +1,7 @@
<script>
import $ from 'jquery';
import { camelCase, difference, union } from 'lodash';
-import updateIssueLabelsMutation from '~/boards/queries/issue_set_labels.mutation.graphql';
+import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
import createFlash from '~/flash';
import { IssuableType } from '~/issue_show/constants';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/whats_new/components/app.vue b/app/assets/javascripts/whats_new/components/app.vue
index 3c1de57252a..560cabd3bba 100644
--- a/app/assets/javascripts/whats_new/components/app.vue
+++ b/app/assets/javascripts/whats_new/components/app.vue
@@ -2,13 +2,15 @@
import { mapState, mapActions } from 'vuex';
import {
GlDrawer,
- GlBadge,
- GlIcon,
- GlLink,
GlInfiniteScroll,
GlResizeObserverDirective,
+ GlTabs,
+ GlTab,
+ GlBadge,
+ GlLoadingIcon,
} from '@gitlab/ui';
import SkeletonLoader from './skeleton_loader.vue';
+import Feature from './feature.vue';
import Tracking from '~/tracking';
import { getDrawerBodyHeight } from '../utils/get_drawer_body_height';
@@ -17,11 +19,13 @@ const trackingMixin = Tracking.mixin();
export default {
components: {
GlDrawer,
- GlBadge,
- GlIcon,
- GlLink,
GlInfiniteScroll,
+ GlTabs,
+ GlTab,
SkeletonLoader,
+ Feature,
+ GlBadge,
+ GlLoadingIcon,
},
directives: {
GlResizeObserver: GlResizeObserverDirective,
@@ -31,11 +35,19 @@ export default {
storageKey: {
type: String,
required: true,
- default: null,
+ },
+ versions: {
+ type: Array,
+ required: true,
+ },
+ gitlabDotCom: {
+ type: Boolean,
+ required: false,
+ default: false,
},
},
computed: {
- ...mapState(['open', 'features', 'pageInfo', 'drawerBodyHeight']),
+ ...mapState(['open', 'features', 'pageInfo', 'drawerBodyHeight', 'fetching']),
},
mounted() {
this.openDrawer(this.storageKey);
@@ -49,14 +61,25 @@ export default {
methods: {
...mapActions(['openDrawer', 'closeDrawer', 'fetchItems', 'setDrawerBodyHeight']),
bottomReached() {
- if (this.pageInfo.nextPage) {
- this.fetchItems(this.pageInfo.nextPage);
+ const page = this.pageInfo.nextPage;
+ if (page) {
+ this.fetchItems({ page });
}
},
handleResize() {
const height = getDrawerBodyHeight(this.$refs.drawer.$el);
this.setDrawerBodyHeight(height);
},
+ featuresForVersion(version) {
+ return this.features.filter(feature => {
+ return feature.release === parseFloat(version);
+ });
+ },
+ fetchVersion(version) {
+ if (this.featuresForVersion(version).length === 0) {
+ this.fetchItems({ version });
+ }
+ },
},
};
</script>
@@ -73,64 +96,39 @@ export default {
<template #header>
<h4 class="page-title gl-my-2">{{ __("What's new at GitLab") }}</h4>
</template>
- <gl-infinite-scroll
- v-if="features.length"
- :fetched-items="features.length"
- :max-list-height="drawerBodyHeight"
- class="gl-p-0"
- @bottomReached="bottomReached"
- >
- <template #items>
- <div
- v-for="feature in features"
- :key="feature.title"
- class="gl-pb-7 gl-pt-5 gl-px-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
+ <template v-if="features.length">
+ <gl-infinite-scroll
+ v-if="gitlabDotCom"
+ :fetched-items="features.length"
+ :max-list-height="drawerBodyHeight"
+ class="gl-p-0"
+ @bottomReached="bottomReached"
+ >
+ <template #items>
+ <feature v-for="feature in features" :key="feature.title" :feature="feature" />
+ </template>
+ </gl-infinite-scroll>
+ <gl-tabs v-else :style="{ height: `${drawerBodyHeight}px` }" class="gl-p-0">
+ <gl-tab
+ v-for="(version, index) in versions"
+ :key="version"
+ @click="fetchVersion(version)"
>
- <gl-link
- :href="feature.url"
- target="_blank"
- class="whats-new-item-title-link"
- data-track-event="click_whats_new_item"
- :data-track-label="feature.title"
- :data-track-property="feature.url"
- >
- <h5 class="gl-font-lg">{{ feature.title }}</h5>
- </gl-link>
- <div v-if="feature.packages" class="gl-mb-3">
- <gl-badge
- v-for="package_name in feature.packages"
- :key="package_name"
- size="sm"
- class="whats-new-item-badge gl-mr-2"
- >
- <gl-icon name="license" />{{ package_name }}
- </gl-badge>
- </div>
- <gl-link
- :href="feature.url"
- target="_blank"
- data-track-event="click_whats_new_item"
- :data-track-label="feature.title"
- :data-track-property="feature.url"
- >
- <img
- :alt="feature.title"
- :src="feature.image_url"
- class="img-thumbnail gl-px-8 gl-py-3 whats-new-item-image"
+ <template #title>
+ <span>{{ version }}</span>
+ <gl-badge v-if="index === 0">{{ __('Your Version') }}</gl-badge>
+ </template>
+ <gl-loading-icon v-if="fetching" size="lg" class="text-center" />
+ <template v-else>
+ <feature
+ v-for="feature in featuresForVersion(version)"
+ :key="feature.title"
+ :feature="feature"
/>
- </gl-link>
- <p class="gl-pt-3">{{ feature.body }}</p>
- <gl-link
- :href="feature.url"
- target="_blank"
- data-track-event="click_whats_new_item"
- :data-track-label="feature.title"
- :data-track-property="feature.url"
- >{{ __('Learn more') }}</gl-link
- >
- </div>
- </template>
- </gl-infinite-scroll>
+ </template>
+ </gl-tab>
+ </gl-tabs>
+ </template>
<div v-else class="gl-mt-5">
<skeleton-loader />
<skeleton-loader />
diff --git a/app/assets/javascripts/whats_new/components/feature.vue b/app/assets/javascripts/whats_new/components/feature.vue
new file mode 100644
index 00000000000..32fb2bd34a5
--- /dev/null
+++ b/app/assets/javascripts/whats_new/components/feature.vue
@@ -0,0 +1,64 @@
+<script>
+import { GlBadge, GlIcon, GlLink } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlBadge,
+ GlIcon,
+ GlLink,
+ },
+ props: {
+ feature: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-pb-7 gl-pt-5 gl-px-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100">
+ <gl-link
+ :href="feature.url"
+ target="_blank"
+ class="whats-new-item-title-link"
+ data-track-event="click_whats_new_item"
+ :data-track-label="feature.title"
+ :data-track-property="feature.url"
+ >
+ <h5 class="gl-font-lg" data-test-id="feature-title">{{ feature.title }}</h5>
+ </gl-link>
+ <div v-if="feature.packages" class="gl-mb-3">
+ <gl-badge
+ v-for="packageName in feature.packages"
+ :key="packageName"
+ size="sm"
+ class="whats-new-item-badge gl-mr-2"
+ >
+ <gl-icon name="license" />{{ packageName }}
+ </gl-badge>
+ </div>
+ <gl-link
+ :href="feature.url"
+ target="_blank"
+ data-track-event="click_whats_new_item"
+ :data-track-label="feature.title"
+ :data-track-property="feature.url"
+ >
+ <img
+ :alt="feature.title"
+ :src="feature.image_url"
+ class="img-thumbnail gl-px-8 gl-py-3 whats-new-item-image"
+ />
+ </gl-link>
+ <p class="gl-pt-3">{{ feature.body }}</p>
+ <gl-link
+ :href="feature.url"
+ target="_blank"
+ data-track-event="click_whats_new_item"
+ :data-track-label="feature.title"
+ :data-track-property="feature.url"
+ >{{ __('Learn more') }}</gl-link
+ >
+ </div>
+</template>
diff --git a/app/assets/javascripts/whats_new/index.js b/app/assets/javascripts/whats_new/index.js
index 2b9e7a2815e..ed0258c3992 100644
--- a/app/assets/javascripts/whats_new/index.js
+++ b/app/assets/javascripts/whats_new/index.js
@@ -10,8 +10,6 @@ export default el => {
if (whatsNewApp) {
store.dispatch('openDrawer');
} else {
- const storageKey = getStorageKey(el);
-
whatsNewApp = new Vue({
el,
store,
@@ -28,7 +26,11 @@ export default el => {
},
render(createElement) {
return createElement('app', {
- props: { storageKey },
+ props: {
+ storageKey: getStorageKey(el),
+ versions: JSON.parse(el.getAttribute('data-versions')),
+ gitlabDotCom: el.getAttribute('data-gitlab-dot-com'),
+ },
});
},
});
diff --git a/app/assets/javascripts/whats_new/store/actions.js b/app/assets/javascripts/whats_new/store/actions.js
index 532febd61cb..0e5eeda742a 100644
--- a/app/assets/javascripts/whats_new/store/actions.js
+++ b/app/assets/javascripts/whats_new/store/actions.js
@@ -13,7 +13,7 @@ export default {
localStorage.setItem(storageKey, JSON.stringify(false));
}
},
- fetchItems({ commit, state }, page) {
+ fetchItems({ commit, state }, { page, version } = { page: null, version: null }) {
if (state.fetching) {
return false;
}
@@ -24,6 +24,7 @@ export default {
.get('/-/whats_new', {
params: {
page,
+ version,
},
})
.then(({ data, headers }) => {
diff --git a/app/assets/stylesheets/components/whats_new.scss b/app/assets/stylesheets/components/whats_new.scss
index 64e82531c30..51bf2686be2 100644
--- a/app/assets/stylesheets/components/whats_new.scss
+++ b/app/assets/stylesheets/components/whats_new.scss
@@ -6,6 +6,32 @@
.gl-infinite-scroll-legend {
@include gl-display-none;
}
+
+ .gl-tabs {
+ @include gl-overflow-y-auto;
+ }
+
+ .gl-tabs-nav {
+ flex-wrap: nowrap;
+ overflow-x: scroll;
+ align-items: stretch;
+
+ .nav-item {
+ @include gl-flex-shrink-0;
+
+ a {
+ @include gl-h-full;
+ line-height: 1.5;
+ }
+ }
+ }
+
+ .gl-spinner-container {
+ @include gl-w-full;
+ @include gl-absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ }
}
.with-performance-bar .whats-new-drawer {
diff --git a/app/assets/stylesheets/page_bundles/oncall_schedules.scss b/app/assets/stylesheets/page_bundles/oncall_schedules.scss
index 4a96d4fa612..9624c5095cc 100644
--- a/app/assets/stylesheets/page_bundles/oncall_schedules.scss
+++ b/app/assets/stylesheets/page_bundles/oncall_schedules.scss
@@ -28,3 +28,115 @@
}
}
}
+
+//// Copied from roadmaps.scss - adapted for on-call schedules
+$header-item-height: 60px;
+$details-cell-width: px-to-rem(150px);
+$timeline-cell-height: 32px;
+$timeline-cell-width: 180px;
+$border-style: 1px solid var(--gray-100, $gray-100);
+$gradient-dark-gray: rgba(0, 0, 0, 0.15);
+$gradient-gray: rgba(255, 255, 255, 0.001);
+$scroll-top-gradient: linear-gradient(to bottom, $gradient-dark-gray 0%, $gradient-gray 100%);
+$scroll-bottom-gradient: linear-gradient(to bottom, $gradient-gray 0%, $gradient-dark-gray 100%);
+$column-right-gradient: linear-gradient(to right, $gradient-dark-gray 0%, $gradient-gray 100%);
+$epic-details-cell-width: 150px;
+
+.schedule-shell {
+ @include gl-relative;
+ @include gl-h-full;
+ @include gl-w-full;
+ @include gl-overflow-x-auto;
+ @include gl-border-gray-100;
+ @include gl-border-1;
+ @include gl-border-solid;
+ @include gl-rounded-base;
+}
+
+.timeline-section {
+ @include gl-sticky;
+ position: -webkit-sticky;
+ @include gl-top-0;
+ z-index: 20;
+
+ .timeline-header-blank,
+ .timeline-header-item {
+ @include float-left;
+ height: $header-item-height;
+ border-bottom: $border-style;
+ background-color: var(--white, $white);
+ }
+
+ .timeline-header-blank {
+ @include gl-sticky;
+ position: -webkit-sticky;
+ @include gl-top-0;
+ @include gl-left-0;
+ width: $details-cell-width;
+ z-index: 2;
+
+ &::after {
+ height: $header-item-height;
+ @include gl-content-empty;
+ @include gl-absolute;
+ @include gl-top-0;
+ right: -$grid-size;
+ width: $grid-size;
+ @include gl-pointer-events-none;
+ background: $column-right-gradient;
+ }
+ }
+
+ .timeline-header-item {
+ // container size minus left panel width divided by 2 week timeframes
+ width: calc((100% - #{$epic-details-cell-width}) / 2);
+
+ &:last-of-type .item-label {
+ @include gl-border-r-0;
+ }
+
+ .item-label,
+ .item-sublabel .sublabel-value {
+ color: var(--gray-400, $gray-400);
+ @include gl-font-weight-normal;
+
+ &.label-dark {
+ @include gl-text-gray-900;
+ }
+
+ &.label-bold {
+ @include gl-font-weight-bold;
+ }
+ }
+
+ .item-label {
+ padding: $gl-padding-8 $gl-padding;
+ border-right: $border-style;
+ border-bottom: $border-style;
+ }
+
+ .item-sublabel {
+ @include gl-relative;
+ @include gl-display-flex;
+
+ .sublabel-value {
+ @include gl-flex-grow-1;
+ @include gl-flex-basis-0;
+
+ text-align: center;
+ font-size: $code-font-size;
+ line-height: 1.5;
+ padding: 2px 0;
+ }
+ }
+
+ .current-day-indicator-header {
+ @include gl-bottom-0;
+ height: $gl-vert-padding;
+ width: $gl-vert-padding;
+ background-color: var(--red-500, $red-500);
+ border-radius: 50%;
+ transform: translateX(-3px);
+ }
+ }
+}
diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb
index 6ed15d9b127..cba86c65848 100644
--- a/app/controllers/whats_new_controller.rb
+++ b/app/controllers/whats_new_controller.rb
@@ -1,16 +1,19 @@
# frozen_string_literal: true
class WhatsNewController < ApplicationController
+ include Gitlab::Utils::StrongMemoize
+
skip_before_action :authenticate_user!
- before_action :check_feature_flag, :check_valid_page_param, :set_pagination_headers
+ before_action :check_feature_flag
+ before_action :check_valid_page_param, :set_pagination_headers, unless: -> { has_version_param? }
feature_category :navigation
def index
respond_to do |format|
format.js do
- render json: most_recent_items
+ render json: highlight_items
end
end
end
@@ -29,15 +32,25 @@ class WhatsNewController < ApplicationController
params[:page]&.to_i || 1
end
- def most_recent
- @most_recent ||= ReleaseHighlight.paginated(page: current_page)
+ def highlights
+ strong_memoize(:highlights) do
+ if has_version_param?
+ ReleaseHighlight.for_version(version: params[:version])
+ else
+ ReleaseHighlight.paginated(page: current_page)
+ end
+ end
end
- def most_recent_items
- most_recent[:items].map {|item| Gitlab::WhatsNew::ItemPresenter.present(item) }
+ def highlight_items
+ highlights.map {|item| Gitlab::WhatsNew::ItemPresenter.present(item) }
end
def set_pagination_headers
- response.set_header('X-Next-Page', most_recent[:next_page])
+ response.set_header('X-Next-Page', highlights.next_page)
+ end
+
+ def has_version_param?
+ params[:version].present?
end
end
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
index f267ede3153..bbf5bde5904 100644
--- a/app/helpers/whats_new_helper.rb
+++ b/app/helpers/whats_new_helper.rb
@@ -6,10 +6,14 @@ module WhatsNewHelper
end
def whats_new_storage_key
- most_recent_version = ReleaseHighlight.most_recent_version
+ most_recent_version = ReleaseHighlight.versions&.first
return unless most_recent_version
['display-whats-new-notification', most_recent_version].join('-')
end
+
+ def whats_new_versions
+ ReleaseHighlight.versions
+ end
end
diff --git a/app/models/release_highlight.rb b/app/models/release_highlight.rb
index 436314de3a3..53545ad8933 100644
--- a/app/models/release_highlight.rb
+++ b/app/models/release_highlight.rb
@@ -3,6 +3,17 @@
class ReleaseHighlight
CACHE_DURATION = 1.hour
FILES_PATH = Rails.root.join('data', 'whats_new', '*.yml')
+ RELEASE_VERSIONS_IN_A_YEAR = 12
+
+ def self.for_version(version:)
+ index = self.versions.index(version)
+
+ return if index.nil?
+
+ page = index + 1
+
+ self.paginated(page: page)
+ end
def self.paginated(page: 1)
Rails.cache.fetch(cache_key(page), expires_in: CACHE_DURATION) do
@@ -10,10 +21,7 @@ class ReleaseHighlight
next if items.nil?
- {
- items: items,
- next_page: next_page(current_page: page)
- }
+ QueryResult.new(items: items, next_page: next_page(current_page: page))
end
end
@@ -53,15 +61,25 @@ class ReleaseHighlight
next_page if self.file_paths[next_index]
end
- def self.most_recent_version
- Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:release_version', expires_in: CACHE_DURATION) do
- self.paginated&.[](:items)&.first&.[]('release')
+ def self.most_recent_item_count
+ Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:recent_item_count', expires_in: CACHE_DURATION) do
+ self.paginated&.items&.count
end
end
- def self.most_recent_item_count
- Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:recent_item_count', expires_in: CACHE_DURATION) do
- self.paginated&.[](:items)&.count
+ def self.versions
+ Gitlab::ProcessMemoryCache.cache_backend.fetch('release_highlight:versions', expires_in: CACHE_DURATION) do
+ versions = self.file_paths.first(RELEASE_VERSIONS_IN_A_YEAR).map do |path|
+ /\d*\_(\d*\_\d*)\.yml$/.match(path).captures[0].gsub(/0(?=\d)/, "").tr("_", ".")
+ end
+
+ versions.uniq
end
end
+
+ QueryResult = Struct.new(:items, :next_page, keyword_init: true) do
+ include Enumerable
+
+ delegate :each, to: :items
+ end
end
diff --git a/app/models/service.rb b/app/models/service.rb
index f9ef7230661..c94b9c3b1cc 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -70,6 +70,7 @@ class Service < ApplicationRecord
scope :by_type, -> (type) { where(type: type) }
scope :by_active_flag, -> (flag) { where(active: flag) }
scope :inherit_from_id, -> (id) { where(inherit_from_id: id) }
+ scope :inherit, -> { where.not(inherit_from_id: nil) }
scope :for_group, -> (group) { where(group_id: group, type: available_services_types(include_project_specific: false)) }
scope :for_template, -> { where(template: true, type: available_services_types(include_project_specific: false)) }
scope :for_instance, -> { where(instance: true, type: available_services_types(include_project_specific: false)) }
@@ -278,7 +279,7 @@ class Service < ApplicationRecord
active.where(instance: true),
active.where(group_id: group_ids, inherit_from_id: nil)
]).order(Arel.sql("type ASC, array_position(#{array}::bigint[], services.group_id), instance DESC")).group_by(&:type).each do |type, records|
- build_from_integration(records.first, association => scope.id).save!
+ build_from_integration(records.first, association => scope.id).save
end
end
diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb
index aad574aeaf5..e800e546a45 100644
--- a/app/services/groups/transfer_service.rb
+++ b/app/services/groups/transfer_service.rb
@@ -28,9 +28,11 @@ module Groups
Group.transaction do
update_group_attributes
ensure_ownership
+ update_integrations
end
post_update_hooks(@updated_project_ids)
+ propagate_integrations
true
end
@@ -196,6 +198,17 @@ module Groups
raise TransferError, result[:message] unless result[:status] == :success
end
end
+
+ def update_integrations
+ @group.services.inherit.delete_all
+ Service.create_from_active_default_integrations(@group, :group_id)
+ end
+
+ def propagate_integrations
+ @group.services.inherit.each do |integration|
+ PropagateIntegrationWorker.perform_async(integration.id)
+ end
+ end
end
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 5178c76f0fc..1574c90d2ac 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -59,7 +59,7 @@ module Projects
raise TransferError.new(s_("TransferProject|Root namespace can't be updated if project has NPM packages"))
end
- attempt_transfer_transaction
+ proceed_to_transfer
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -67,7 +67,7 @@ module Projects
new_namespace.root_ancestor == project.namespace.root_ancestor
end
- def attempt_transfer_transaction
+ def proceed_to_transfer
Project.transaction do
project.expire_caches_before_rename(@old_path)
@@ -87,6 +87,8 @@ module Projects
# Move uploads
move_project_uploads(project)
+ update_integrations
+
project.old_path_with_namespace = @old_path
update_repository_configuration(@new_path)
@@ -214,6 +216,11 @@ module Projects
project.shared_runners_enabled = false
end
end
+
+ def update_integrations
+ project.services.inherit.delete_all
+ Service.create_from_active_default_integrations(project, :project_id)
+ end
end
end
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 8aba9426ec0..70ab0a56581 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -102,7 +102,7 @@
= sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left')
- if ::Feature.enabled?(:whats_new_drawer, current_user)
- #whats-new-app{ data: { storage_key: whats_new_storage_key } }
+ #whats-new-app{ data: { storage_key: whats_new_storage_key, versions: whats_new_versions, gitlab_dot_com: Gitlab.dev_env_org_or_com? } }
- if can?(current_user, :update_user_status, current_user)
.js-set-status-modal-wrapper{ data: user_status_data }