1<script>
2import { GlAlert } from '@gitlab/ui';
3import { sortBy } from 'lodash';
4import Draggable from 'vuedraggable';
5import { mapState, mapGetters, mapActions } from 'vuex';
6import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
7import defaultSortableConfig from '~/sortable/sortable_config';
8import { DraggableItemTypes } from '../constants';
9import BoardColumn from './board_column.vue';
10
11export default {
12  draggableItemTypes: DraggableItemTypes,
13  components: {
14    BoardAddNewColumn,
15    BoardColumn,
16    BoardContentSidebar: () => import('~/boards/components/board_content_sidebar.vue'),
17    EpicBoardContentSidebar: () =>
18      import('ee_component/boards/components/epic_board_content_sidebar.vue'),
19    EpicsSwimlanes: () => import('ee_component/boards/components/epics_swimlanes.vue'),
20    GlAlert,
21  },
22  inject: ['canAdminList'],
23  props: {
24    disabled: {
25      type: Boolean,
26      required: true,
27    },
28  },
29  computed: {
30    ...mapState(['boardLists', 'error', 'addColumnForm']),
31    ...mapGetters(['isSwimlanesOn', 'isEpicBoard', 'isIssueBoard']),
32    addColumnFormVisible() {
33      return this.addColumnForm?.visible;
34    },
35    boardListsToUse() {
36      return sortBy([...Object.values(this.boardLists)], 'position');
37    },
38    canDragColumns() {
39      return this.canAdminList;
40    },
41    boardColumnWrapper() {
42      return this.canDragColumns ? Draggable : 'div';
43    },
44    draggableOptions() {
45      const options = {
46        ...defaultSortableConfig,
47        disabled: this.disabled,
48        draggable: '.is-draggable',
49        fallbackOnBody: false,
50        group: 'boards-list',
51        tag: 'div',
52        value: this.boardListsToUse,
53      };
54
55      return this.canDragColumns ? options : {};
56    },
57  },
58  methods: {
59    ...mapActions(['moveList', 'unsetError']),
60    afterFormEnters() {
61      const el = this.canDragColumns ? this.$refs.list.$el : this.$refs.list;
62      el.scrollTo({ left: el.scrollWidth, behavior: 'smooth' });
63    },
64  },
65};
66</script>
67
68<template>
69  <div v-cloak data-qa-selector="boards_list">
70    <gl-alert v-if="error" variant="danger" :dismissible="true" @dismiss="unsetError">
71      {{ error }}
72    </gl-alert>
73    <component
74      :is="boardColumnWrapper"
75      v-if="!isSwimlanesOn"
76      ref="list"
77      v-bind="draggableOptions"
78      class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
79      @end="moveList"
80    >
81      <board-column
82        v-for="(list, index) in boardListsToUse"
83        :key="index"
84        ref="board"
85        :list="list"
86        :data-draggable-item-type="$options.draggableItemTypes.list"
87        :disabled="disabled"
88      />
89
90      <transition name="slide" @after-enter="afterFormEnters">
91        <board-add-new-column v-if="addColumnFormVisible" />
92      </transition>
93    </component>
94
95    <epics-swimlanes
96      v-else-if="boardListsToUse.length"
97      ref="swimlanes"
98      :lists="boardListsToUse"
99      :can-admin-list="canAdminList"
100      :disabled="disabled"
101    />
102
103    <board-content-sidebar v-if="isIssueBoard" data-testid="issue-boards-sidebar" />
104
105    <epic-board-content-sidebar v-else-if="isEpicBoard" data-testid="epic-boards-sidebar" />
106  </div>
107</template>
108