summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/issuable_list
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/issuable_list')
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_item.vue6
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_list_root.vue30
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_tabs.vue13
3 files changed, 43 insertions, 6 deletions
diff --git a/app/assets/javascripts/issuable_list/components/issuable_item.vue b/app/assets/javascripts/issuable_list/components/issuable_item.vue
index 92c527c79ff..5d497369f5a 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_item.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_item.vue
@@ -65,6 +65,9 @@ export default {
labels() {
return this.issuable.labels?.nodes || this.issuable.labels || [];
},
+ labelIdsString() {
+ return JSON.stringify(this.labels.map((label) => label.id));
+ },
assignees() {
return this.issuable.assignees || [];
},
@@ -149,12 +152,13 @@ export default {
</script>
<template>
- <li class="issue gl-px-5!">
+ <li :id="`issuable_${issuable.id}`" class="issue gl-px-5!" :data-labels="labelIdsString">
<div class="issuable-info-container">
<div v-if="showCheckbox" class="issue-check">
<gl-form-checkbox
class="gl-mr-0"
:checked="checked"
+ :data-id="issuable.id"
@input="$emit('checked-input', $event)"
/>
</div>
diff --git a/app/assets/javascripts/issuable_list/components/issuable_list_root.vue b/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
index 40b0fcbb8c6..6b95c3a578e 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
@@ -10,7 +10,14 @@ import IssuableBulkEditSidebar from './issuable_bulk_edit_sidebar.vue';
import IssuableItem from './issuable_item.vue';
import IssuableTabs from './issuable_tabs.vue';
+const VueDraggable = () => import('vuedraggable');
+
export default {
+ vueDraggableAttributes: {
+ animation: 200,
+ ghostClass: 'gl-visibility-hidden',
+ tag: 'ul',
+ },
components: {
GlSkeletonLoading,
IssuableTabs,
@@ -18,6 +25,7 @@ export default {
IssuableItem,
IssuableBulkEditSidebar,
GlPagination,
+ VueDraggable,
},
props: {
namespace: {
@@ -127,6 +135,11 @@ export default {
required: false,
default: null,
},
+ isManualOrdering: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -159,6 +172,9 @@ export default {
return acc;
}, []);
},
+ issuablesWrapper() {
+ return this.isManualOrdering ? VueDraggable : 'ul';
+ },
},
watch: {
issuables(list) {
@@ -202,11 +218,16 @@ export default {
},
handleIssuableCheckedInput(issuable, value) {
this.checkedIssuables[this.issuableId(issuable)].checked = value;
+ this.$emit('update-legacy-bulk-edit');
},
handleAllIssuablesCheckedInput(value) {
Object.keys(this.checkedIssuables).forEach((issuableId) => {
this.checkedIssuables[issuableId].checked = value;
});
+ this.$emit('update-legacy-bulk-edit');
+ },
+ handleVueDraggableUpdate({ newIndex, oldIndex }) {
+ this.$emit('reorder', { newIndex, oldIndex });
},
},
};
@@ -253,13 +274,18 @@ export default {
<gl-skeleton-loading />
</li>
</ul>
- <ul
+ <component
+ :is="issuablesWrapper"
v-if="!issuablesLoading && issuables.length"
class="content-list issuable-list issues-list"
+ :class="{ 'manual-ordering': isManualOrdering }"
+ v-bind="$options.vueDraggableAttributes"
+ @update="handleVueDraggableUpdate"
>
<issuable-item
v-for="issuable in issuables"
:key="issuableId(issuable)"
+ :class="{ 'gl-cursor-grab': isManualOrdering }"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
:enable-label-permalinks="enableLabelPermalinks"
@@ -284,7 +310,7 @@ export default {
<slot name="statistics" :issuable="issuable"></slot>
</template>
</issuable-item>
- </ul>
+ </component>
<slot v-if="!issuablesLoading && !issuables.length" name="empty-state"></slot>
<gl-pagination
v-if="showPaginationControls"
diff --git a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
index 57da030e22e..6bc621b52e6 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
@@ -26,6 +26,9 @@ export default {
isTabActive(tabName) {
return tabName === this.currentTab;
},
+ isTabCountNumeric(tab) {
+ return Number.isInteger(this.tabCounts[tab.name]);
+ },
},
};
</script>
@@ -44,9 +47,13 @@ export default {
>
<template #title>
<span :title="tab.titleTooltip">{{ tab.title }}</span>
- <gl-badge v-if="tabCounts" variant="neutral" size="sm" class="gl-tab-counter-badge">{{
- tabCounts[tab.name]
- }}</gl-badge>
+ <gl-badge
+ v-if="isTabCountNumeric(tab)"
+ variant="neutral"
+ size="sm"
+ class="gl-tab-counter-badge"
+ >{{ tabCounts[tab.name] }}</gl-badge
+ >
</template>
</gl-tab>
</gl-tabs>