1<script>
2import {
3  GlButton,
4  GlDropdown,
5  GlFormGroup,
6  GlIcon,
7  GlSearchBoxByType,
8  GlSkeletonLoader,
9} from '@gitlab/ui';
10import { mapActions } from 'vuex';
11import { __ } from '~/locale';
12
13export default {
14  i18n: {
15    add: __('Add to board'),
16    cancel: __('Cancel'),
17    newList: __('New list'),
18    noResults: __('No matching results'),
19    scope: __('Scope'),
20    scopeDescription: __('Issues must match this scope to appear in this list.'),
21    selected: __('Selected'),
22  },
23  components: {
24    GlButton,
25    GlDropdown,
26    GlFormGroup,
27    GlIcon,
28    GlSearchBoxByType,
29    GlSkeletonLoader,
30  },
31  props: {
32    loading: {
33      type: Boolean,
34      required: true,
35    },
36    searchLabel: {
37      type: String,
38      required: false,
39      default: null,
40    },
41    noneSelected: {
42      type: String,
43      required: true,
44    },
45    searchPlaceholder: {
46      type: String,
47      required: true,
48    },
49    selectedId: {
50      type: [Number, String],
51      required: false,
52      default: null,
53    },
54  },
55  data() {
56    return {
57      searchValue: '',
58    };
59  },
60  watch: {
61    selectedId(val) {
62      if (val) {
63        this.$refs.dropdown.hide(true);
64      }
65    },
66  },
67  methods: {
68    ...mapActions(['setAddColumnFormVisibility']),
69    setFocus() {
70      this.$refs.searchBox.focusInput();
71    },
72    onHide() {
73      this.searchValue = '';
74      this.$emit('filter-items', '');
75      this.$emit('hide');
76    },
77  },
78};
79</script>
80
81<template>
82  <div
83    class="board-add-new-list board gl-display-inline-block gl-h-full gl-px-3 gl-vertical-align-top gl-white-space-normal gl-flex-shrink-0"
84    data-testid="board-add-new-column"
85    data-qa-selector="board_add_new_list"
86  >
87    <div
88      class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base gl-bg-white"
89    >
90      <h3
91        class="gl-font-size-h2 gl-px-5 gl-py-4 gl-m-0 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
92        data-testid="board-add-column-form-title"
93      >
94        {{ $options.i18n.newList }}
95      </h3>
96
97      <div
98        class="gl-display-flex gl-flex-direction-column gl-h-full gl-overflow-y-auto gl-align-items-flex-start"
99      >
100        <div class="gl-px-5">
101          <h3 class="gl-font-lg gl-mt-5 gl-mb-2">
102            {{ $options.i18n.scope }}
103          </h3>
104          <p class="gl-mb-3">{{ $options.i18n.scopeDescription }}</p>
105        </div>
106
107        <slot name="select-list-type"></slot>
108
109        <gl-form-group class="gl-px-5 lg-mb-3 gl-max-w-full" :label="searchLabel">
110          <gl-dropdown
111            ref="dropdown"
112            class="gl-mb-3 gl-max-w-full"
113            toggle-class="gl-max-w-full gl-display-flex gl-align-items-center gl-text-trunate"
114            boundary="viewport"
115            @shown="setFocus"
116            @hide="onHide"
117          >
118            <template #button-content>
119              <slot name="selected">
120                <div>{{ noneSelected }}</div>
121              </slot>
122              <gl-icon class="dropdown-chevron gl-flex-shrink-0" name="chevron-down" />
123            </template>
124
125            <template #header>
126              <gl-search-box-by-type
127                ref="searchBox"
128                v-model="searchValue"
129                debounce="250"
130                class="gl-mt-0!"
131                :placeholder="searchPlaceholder"
132                @input="$emit('filter-items', $event)"
133              />
134            </template>
135
136            <div v-if="loading" class="gl-px-5">
137              <gl-skeleton-loader :width="400" :height="172">
138                <rect width="380" height="20" x="10" y="15" rx="4" />
139                <rect width="280" height="20" x="10" y="50" rx="4" />
140                <rect width="330" height="20" x="10" y="85" rx="4" />
141              </gl-skeleton-loader>
142            </div>
143
144            <slot v-else name="items">
145              <p class="gl-mx-5">{{ $options.i18n.noResults }}</p>
146            </slot>
147          </gl-dropdown>
148        </gl-form-group>
149      </div>
150      <div
151        class="gl-display-flex gl-p-3 gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-bg-gray-10 gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
152      >
153        <gl-button
154          data-testid="cancelAddNewColumn"
155          class="gl-ml-auto gl-mr-3"
156          @click="setAddColumnFormVisibility(false)"
157          >{{ $options.i18n.cancel }}</gl-button
158        >
159        <gl-button
160          data-testid="addNewColumnButton"
161          :disabled="!selectedId"
162          variant="confirm"
163          class="gl-mr-4"
164          @click="$emit('add-list')"
165          >{{ $options.i18n.add }}</gl-button
166        >
167      </div>
168    </div>
169  </div>
170</template>
171