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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 09:09:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 09:09:51 +0300
commitad3b511ba360c7fc09fe519396c6d15f09845d66 (patch)
tree349d48c43bd9c48fd1bc93028c21c0ac715e752d /app/assets/javascripts/boards
parentf3f9b9fe66f234528706fbe0e70a0e529b5d8d08 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/boards')
-rw-r--r--app/assets/javascripts/boards/components/board_card.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_card_inner.vue9
-rw-r--r--app/assets/javascripts/boards/components/board_card_move_to_position.vue140
-rw-r--r--app/assets/javascripts/boards/constants.js2
-rw-r--r--app/assets/javascripts/boards/stores/actions.js3
5 files changed, 153 insertions, 3 deletions
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index 3638fdd2ca5..192bc4b5d25 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -98,6 +98,6 @@ export default {
class="board-card gl-p-5 gl-rounded-base"
@click="toggleIssue($event)"
>
- <board-card-inner :list="list" :item="item" :update-filters="true" />
+ <board-card-inner :list="list" :item="item" :update-filters="true" :index="index" />
</li>
</template>
diff --git a/app/assets/javascripts/boards/components/board_card_inner.vue b/app/assets/javascripts/boards/components/board_card_inner.vue
index 8dc521317cd..a9a4912d9e9 100644
--- a/app/assets/javascripts/boards/components/board_card_inner.vue
+++ b/app/assets/javascripts/boards/components/board_card_inner.vue
@@ -15,6 +15,7 @@ import { updateHistory } from '~/lib/utils/url_utility';
import { sprintf, __, n__ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+import BoardCardMoveToPosition from '~/boards/components/board_card_move_to_position.vue';
import { ListType } from '../constants';
import eventHub from '../eventhub';
import BoardBlockedIcon from './board_blocked_icon.vue';
@@ -34,6 +35,7 @@ export default {
IssueCardWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
BoardBlockedIcon,
GlSprintf,
+ BoardCardMoveToPosition,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -55,6 +57,10 @@ export default {
required: false,
default: false,
},
+ index: {
+ type: Number,
+ required: true,
+ },
},
data() {
return {
@@ -202,7 +208,7 @@ export default {
<template>
<div>
<div class="gl-display-flex" dir="auto">
- <h4 class="board-card-title gl-mb-0 gl-mt-0">
+ <h4 class="board-card-title gl-mb-0 gl-mt-0 gl-mr-3">
<board-blocked-icon
v-if="item.blocked"
:item="item"
@@ -235,6 +241,7 @@ export default {
>{{ item.title }}</a
>
</h4>
+ <board-card-move-to-position :item="item" :list="list" :index="index" />
</div>
<div v-if="showLabelFooter" class="board-card-labels gl-mt-2 gl-display-flex gl-flex-wrap">
<template v-for="label in orderedLabels">
diff --git a/app/assets/javascripts/boards/components/board_card_move_to_position.vue b/app/assets/javascripts/boards/components/board_card_move_to_position.vue
new file mode 100644
index 00000000000..053dbb62b2e
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_card_move_to_position.vue
@@ -0,0 +1,140 @@
+<script>
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { mapActions, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
+import { DEFAULT_BOARD_LIST_ITEMS_SIZE } from 'ee_else_ce/boards/constants';
+
+import Tracking from '~/tracking';
+
+export default {
+ i18n: {
+ moveToStartText: s__('Boards|Move to start of list'),
+ moveToEndText: s__('Boards|Move to end of list'),
+ },
+ name: 'BoardCardMoveToPosition',
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ },
+ mixins: [Tracking.mixin()],
+ props: {
+ item: {
+ type: Object,
+ required: true,
+ validator: (item) => ['id', 'iid', 'referencePath'].every((key) => item[key]),
+ },
+ list: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ index: {
+ type: Number,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters(['getBoardItemsByList']),
+ tracking() {
+ return {
+ category: 'boards:list',
+ label: 'move_to_position',
+ property: `type_card`,
+ };
+ },
+ listItems() {
+ return this.getBoardItemsByList(this.list.id);
+ },
+ firstItemInListId() {
+ return this.listItems[0]?.id;
+ },
+ lengthOfListItemsInBoard() {
+ return this.listItems?.length;
+ },
+ lastItemInTheListId() {
+ return this.listItems[this.lengthOfListItemsInBoard - 1]?.id;
+ },
+ itemIdentifier() {
+ return `${this.item.id}-${this.item.iid}-${this.index}`;
+ },
+ showMoveToEndOfList() {
+ return this.lengthOfListItemsInBoard <= DEFAULT_BOARD_LIST_ITEMS_SIZE;
+ },
+ isFirstItemInList() {
+ return this.index === 0;
+ },
+ isLastItemInList() {
+ return this.index === this.lengthOfListItemsInBoard - 1;
+ },
+ },
+ methods: {
+ ...mapActions(['moveItem']),
+ moveToStart() {
+ this.track('click_toggle_button', {
+ label: 'move_to_start',
+ });
+ /** in case it is the first in the list don't call any action/mutation * */
+ if (this.isFirstItemInList) {
+ return;
+ }
+ const moveAfterId = this.firstItemInListId;
+ this.moveToPosition({
+ moveAfterId,
+ });
+ },
+ moveToEnd() {
+ this.track('click_toggle_button', {
+ label: 'move_to_end',
+ });
+ /** in case it is the last in the list don't call any action/mutation * */
+ if (this.isLastItemInList) {
+ return;
+ }
+ const moveBeforeId = this.lastItemInTheListId;
+ this.moveToPosition({
+ moveBeforeId,
+ });
+ },
+ moveToPosition({ moveAfterId, moveBeforeId }) {
+ this.moveItem({
+ itemId: this.item.id,
+ itemIid: this.item.iid,
+ itemPath: this.item.referencePath,
+ fromListId: this.list.id,
+ toListId: this.list.id,
+ moveAfterId,
+ moveBeforeId,
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ ref="dropdown"
+ :key="itemIdentifier"
+ data-testid="move-card-dropdown"
+ icon="ellipsis_v"
+ :text="s__('Boards|Move card')"
+ :text-sr-only="true"
+ class="move-to-position gl-display-block gl-mb-2 gl-ml-2 gl-mt-n3 gl-mr-n3"
+ category="tertiary"
+ :tabindex="index"
+ no-caret
+ @keydown.esc.native="$emit('hide')"
+ >
+ <div>
+ <gl-dropdown-item data-testid="action-move-to-first" @click.stop="moveToStart">
+ {{ $options.i18n.moveToStartText }}
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ v-if="showMoveToEndOfList"
+ data-testid="action-move-to-end"
+ @click.stop="moveToEnd"
+ >
+ {{ $options.i18n.moveToEndText }}
+ </gl-dropdown-item>
+ </div>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js
index 0f290f566ba..d745eed556f 100644
--- a/app/assets/javascripts/boards/constants.js
+++ b/app/assets/javascripts/boards/constants.js
@@ -146,3 +146,5 @@ export default {
BoardType,
ListType,
};
+
+export const DEFAULT_BOARD_LIST_ITEMS_SIZE = 10;
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 791182af806..f84274104b2 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -15,6 +15,7 @@ import {
FilterFields,
ListTypeTitles,
DraggableItemTypes,
+ DEFAULT_BOARD_LIST_ITEMS_SIZE,
} from 'ee_else_ce/boards/constants';
import {
formatIssueInput,
@@ -429,7 +430,7 @@ export default {
filters: filterParams,
isGroup: boardType === BoardType.group,
isProject: boardType === BoardType.project,
- first: 10,
+ first: DEFAULT_BOARD_LIST_ITEMS_SIZE,
after: fetchNext ? state.pageInfoByListId[listId].endCursor : undefined,
};