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
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/boards/components/board_column.vue16
-rw-r--r--app/assets/javascripts/boards/components/board_column_deprecated.vue11
-rw-r--r--app/assets/javascripts/boards/constants.js2
-rw-r--r--app/assets/javascripts/boards/models/list.js1
-rw-r--r--app/assets/javascripts/boards/stores/actions.js27
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js7
-rw-r--r--app/assets/javascripts/boards/stores/getters.js3
-rw-r--r--app/assets/javascripts/boards/stores/mutation_types.js2
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js8
-rw-r--r--app/assets/javascripts/boards/stores/state.js1
-rw-r--r--app/assets/javascripts/profile/profile.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js5
-rw-r--r--app/assets/stylesheets/page_bundles/boards.scss41
-rw-r--r--app/assets/stylesheets/pages/commits.scss24
15 files changed, 146 insertions, 4 deletions
diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue
index 2586351208c..41b9ee795eb 100644
--- a/app/assets/javascripts/boards/components/board_column.vue
+++ b/app/assets/javascripts/boards/components/board_column.vue
@@ -31,8 +31,11 @@ export default {
},
},
computed: {
- ...mapState(['filterParams']),
+ ...mapState(['filterParams', 'highlightedLists']),
...mapGetters(['getIssuesByList']),
+ highlighted() {
+ return this.highlightedLists.includes(this.list.id);
+ },
listIssues() {
return this.getIssuesByList(this.list.id);
},
@@ -48,6 +51,16 @@ export default {
deep: true,
immediate: true,
},
+ highlighted: {
+ handler(highlighted) {
+ if (highlighted) {
+ this.$nextTick(() => {
+ this.$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
+ });
+ }
+ },
+ immediate: true,
+ },
},
methods: {
...mapActions(['fetchIssuesForList']),
@@ -68,6 +81,7 @@ export default {
>
<div
class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base"
+ :class="{ 'board-column-highlighted': highlighted }"
>
<board-list-header :can-admin-list="canAdminList" :list="list" :disabled="disabled" />
<board-list
diff --git a/app/assets/javascripts/boards/components/board_column_deprecated.vue b/app/assets/javascripts/boards/components/board_column_deprecated.vue
index b7931adf067..3dc77654e28 100644
--- a/app/assets/javascripts/boards/components/board_column_deprecated.vue
+++ b/app/assets/javascripts/boards/components/board_column_deprecated.vue
@@ -54,6 +54,16 @@ export default {
},
deep: true,
},
+ 'list.highlighted': {
+ handler(highlighted) {
+ if (highlighted) {
+ this.$nextTick(() => {
+ this.$el.scrollIntoView({ behavior: 'smooth', block: 'start' });
+ });
+ }
+ },
+ immediate: true,
+ },
},
mounted() {
const instance = this;
@@ -98,6 +108,7 @@ export default {
>
<div
class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base"
+ :class="{ 'board-column-highlighted': list.highlighted }"
>
<board-list-header :can-admin-list="canAdminList" :list="list" :disabled="disabled" />
<board-list ref="board-list" :disabled="disabled" :issues="listIssues" :list="list" />
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index f45c5d8fbcd..3ab89b2c9da 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -34,6 +34,8 @@ export const LIST = 'list';
export const NOT_FILTER = 'not[';
+export const flashAnimationDuration = 2000;
+
export default {
BoardType,
ListType,
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
index f6681193dcb..6c6e2522d92 100644
--- a/app/assets/javascripts/boards/models/list.js
+++ b/app/assets/javascripts/boards/models/list.js
@@ -44,6 +44,7 @@ class List {
this.isExpandable = Boolean(typeInfo.isExpandable);
this.isExpanded = !obj.collapsed;
this.page = 1;
+ this.highlighted = obj.highlighted;
this.loading = true;
this.loadingMore = false;
this.issues = obj.issues || [];
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 5ef3147a0a9..e2d07f9128c 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -1,7 +1,7 @@
import { pick } from 'lodash';
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
-import { BoardType, ListType, inactiveId } from '~/boards/constants';
+import { BoardType, ListType, inactiveId, flashAnimationDuration } from '~/boards/constants';
import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
@@ -110,9 +110,31 @@ export default {
.catch(() => commit(types.RECEIVE_BOARD_LISTS_FAILURE));
},
- createList: ({ state, commit, dispatch }, { backlog, labelId, milestoneId, assigneeId }) => {
+ highlightList: ({ commit, state }, listId) => {
+ if ([ListType.backlog, ListType.closed].includes(state.boardLists[listId].listType)) {
+ return;
+ }
+
+ commit(types.ADD_LIST_TO_HIGHLIGHTED_LISTS, listId);
+
+ setTimeout(() => {
+ commit(types.REMOVE_LIST_FROM_HIGHLIGHTED_LISTS, listId);
+ }, flashAnimationDuration);
+ },
+
+ createList: (
+ { state, commit, dispatch, getters },
+ { backlog, labelId, milestoneId, assigneeId },
+ ) => {
const { boardId } = state;
+ const existingList = getters.getListByLabelId(labelId);
+
+ if (existingList) {
+ dispatch('highlightList', existingList.id);
+ return;
+ }
+
gqlClient
.mutate({
mutation: createBoardListMutation,
@@ -130,6 +152,7 @@ export default {
} else {
const list = data.boardListCreate?.list;
dispatch('addList', list);
+ dispatch('highlightList', list.id);
}
})
.catch(() => commit(types.CREATE_LIST_FAILURE));
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index de6d03669f7..39d95552084 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -14,7 +14,7 @@ import {
convertObjectPropsToCamelCase,
} from '~/lib/utils/common_utils';
import { mergeUrlParams } from '~/lib/utils/url_utility';
-import { ListType } from '../constants';
+import { ListType, flashAnimationDuration } from '../constants';
import eventHub from '../eventhub';
import ListAssignee from '../models/assignee';
import ListLabel from '../models/label';
@@ -106,6 +106,11 @@ const boardsStore = {
list
.save()
.then(() => {
+ list.highlighted = true;
+ setTimeout(() => {
+ list.highlighted = false;
+ }, flashAnimationDuration);
+
// Remove any new issues from the backlog
// as they will be visible in the new list
list.issues.forEach(backlogList.removeIssue.bind(backlogList));
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index 827c1e377cf..cab97088bc6 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -28,6 +28,9 @@ export default {
},
getListByLabelId: (state) => (labelId) => {
+ if (!labelId) {
+ return null;
+ }
return find(state.boardLists, (l) => l.label?.id === labelId);
},
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 5ec0ee158df..a89e961ae2d 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -43,3 +43,5 @@ export const SET_SELECTED_PROJECT = 'SET_SELECTED_PROJECT';
export const ADD_BOARD_ITEM_TO_SELECTION = 'ADD_BOARD_ITEM_TO_SELECTION';
export const REMOVE_BOARD_ITEM_FROM_SELECTION = 'REMOVE_BOARD_ITEM_FROM_SELECTION';
export const SET_ADD_COLUMN_FORM_VISIBLE = 'SET_ADD_COLUMN_FORM_VISIBLE';
+export const ADD_LIST_TO_HIGHLIGHTED_LISTS = 'ADD_LIST_TO_HIGHLIGHTED_LISTS';
+export const REMOVE_LIST_FROM_HIGHLIGHTED_LISTS = 'REMOVE_LIST_FROM_HIGHLIGHTED_LISTS';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 09f7f267ee3..79c98c3d90c 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -274,4 +274,12 @@ export default {
[mutationTypes.SET_ADD_COLUMN_FORM_VISIBLE]: (state, visible) => {
state.addColumnFormVisible = visible;
},
+
+ [mutationTypes.ADD_LIST_TO_HIGHLIGHTED_LISTS]: (state, listId) => {
+ state.highlightedLists.push(listId);
+ },
+
+ [mutationTypes.REMOVE_LIST_FROM_HIGHLIGHTED_LISTS]: (state, listId) => {
+ state.highlightedLists = state.highlightedLists.filter((id) => id !== listId);
+ },
};
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index badbd2d80e5..91544d6c9c5 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -15,6 +15,7 @@ export default () => ({
filterParams: {},
boardConfig: {},
labels: [],
+ highlightedLists: [],
selectedBoardItems: [],
groupProjects: [],
groupProjectsFlags: {
diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js
index 300dd5ecc51..a7332b81b9f 100644
--- a/app/assets/javascripts/profile/profile.js
+++ b/app/assets/javascripts/profile/profile.js
@@ -42,6 +42,7 @@ export default class Profile {
$('#user_notification_email').on('select2-selecting', (event) => {
setTimeout(this.submitForm.bind(event.currentTarget));
});
+ $('#user_email_opted_in').on('change', this.submitForm);
$('#user_notified_of_own_activity').on('change', this.submitForm);
this.form.on('submit', this.onSubmitForm);
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
index b284bb23969..13ea07884b1 100644
--- a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
@@ -14,6 +14,7 @@ query getState($projectPath: ID!, $iid: String!) {
pipelines(first: 1) {
nodes {
status
+ warnings
}
}
shouldBeRebased
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 78a17493d31..a0f14f558d2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -172,6 +172,11 @@ export default class MergeRequestStore {
this.canBeMerged = mergeRequest.mergeStatus === 'can_be_merged';
this.canMerge = mergeRequest.userPermissions.canMerge;
this.ciStatus = pipeline?.status.toLowerCase();
+
+ if (pipeline?.warnings && this.ciStatus === 'success') {
+ this.ciStatus = `${this.ciStatus}-with-warnings`;
+ }
+
this.commitsCount = mergeRequest.commitCount || 10;
this.branchMissing = !mergeRequest.sourceBranchExists || !mergeRequest.targetBranchExists;
this.hasConflicts = mergeRequest.conflicts;
diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss
index 3d1ae3519a9..620b37914d8 100644
--- a/app/assets/stylesheets/page_bundles/boards.scss
+++ b/app/assets/stylesheets/page_bundles/boards.scss
@@ -138,6 +138,47 @@
border: 1px solid var(--gray-100, $gray-100);
}
+// to highlight columns we have animated pulse of box-shadow
+// we don't want to actually animate the box-shadow property
+// because that causes costly repaints. Instead we can add a
+// pseudo-element that is the same size as our element, then
+// animate opacity/transform to give a soothing single pulse
+.board-column-highlighted::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ pointer-events: none;
+ opacity: 0;
+ z-index: -1;
+ box-shadow: 0 0 6px 3px $blue-200;
+ animation-name: board-column-flash-border;
+ animation-duration: 1.2s;
+ animation-fill-mode: forwards;
+ animation-timing-function: ease-in-out;
+}
+
+@keyframes board-column-flash-border {
+ 0%,
+ 100% {
+ opacity: 0;
+ transform: scale(0.98);
+ }
+
+ 25%,
+ 75% {
+ opacity: 1;
+ transform: scale(0.99);
+ }
+
+ 50% {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
.board-header {
&.has-border::before {
border-top: 3px solid;
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 226c7867eca..7111d3d4107 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -108,6 +108,30 @@
}
}
+.text-expander {
+ display: inline-flex;
+ background: $white;
+ color: $gl-text-color-secondary;
+ padding: 1px $gl-padding-4;
+ cursor: pointer;
+ border: 1px solid $border-white-normal;
+ border-radius: $border-radius-default;
+ margin-left: 5px;
+ font-size: 12px;
+ line-height: $gl-font-size;
+ outline: none;
+
+ &.open {
+ background-color: darken($gray-light, 10%);
+ box-shadow: inset 0 0 2px rgba($black, 0.2);
+ }
+
+ &:hover {
+ background-color: darken($gray-light, 10%);
+ text-decoration: none;
+ }
+}
+
.commit.flex-list {
display: flex;
}