diff options
Diffstat (limited to 'app/assets/javascripts/boards/components/board_card_move_to_position.vue')
-rw-r--r-- | app/assets/javascripts/boards/components/board_card_move_to_position.vue | 128 |
1 files changed, 128 insertions, 0 deletions
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..ff938219475 --- /dev/null +++ b/app/assets/javascripts/boards/components/board_card_move_to_position.vue @@ -0,0 +1,128 @@ +<script> +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import { mapActions, mapGetters, mapState } from 'vuex'; +import { s__ } from '~/locale'; + +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: { + ...mapState(['pageInfoByListId']), + ...mapGetters(['getBoardItemsByList']), + tracking() { + return { + category: 'boards:list', + label: 'move_to_position', + property: `type_card`, + }; + }, + listItems() { + return this.getBoardItemsByList(this.list.id); + }, + listHasNextPage() { + return this.pageInfoByListId[this.list.id]?.hasNextPage; + }, + lengthOfListItemsInBoard() { + return this.listItems?.length; + }, + itemIdentifier() { + return `${this.item.id}-${this.item.iid}-${this.index}`; + }, + 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; + } + this.moveToPosition({ + positionInList: 0, + }); + }, + 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; + } + this.moveToPosition({ + positionInList: -1, + }); + }, + moveToPosition({ positionInList }) { + this.moveItem({ + itemId: this.item.id, + itemIid: this.item.iid, + itemPath: this.item.referencePath, + fromListId: this.list.id, + toListId: this.list.id, + positionInList, + atIndex: this.index, + allItemsLoadedInList: !this.listHasNextPage, + }); + }, + }, +}; +</script> + +<template> + <gl-dropdown + ref="dropdown" + :key="itemIdentifier" + 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 @click.stop="moveToStart"> + {{ $options.i18n.moveToStartText }} + </gl-dropdown-item> + <gl-dropdown-item @click.stop="moveToEnd"> + {{ $options.i18n.moveToEndText }} + </gl-dropdown-item> + </div> + </gl-dropdown> +</template> |