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:
Diffstat (limited to 'app/assets/javascripts/work_items/components/work_item_ancestors/disclosure_hierarchy.vue')
-rw-r--r--app/assets/javascripts/work_items/components/work_item_ancestors/disclosure_hierarchy.vue127
1 files changed, 127 insertions, 0 deletions
diff --git a/app/assets/javascripts/work_items/components/work_item_ancestors/disclosure_hierarchy.vue b/app/assets/javascripts/work_items/components/work_item_ancestors/disclosure_hierarchy.vue
new file mode 100644
index 00000000000..708121ee210
--- /dev/null
+++ b/app/assets/javascripts/work_items/components/work_item_ancestors/disclosure_hierarchy.vue
@@ -0,0 +1,127 @@
+<script>
+import uniqueId from 'lodash/uniqueId';
+import { GlIcon, GlTooltip, GlDisclosureDropdown } from '@gitlab/ui';
+import DisclosureHierarchyItem from './disclosure_hierarchy_item.vue';
+
+export default {
+ components: {
+ GlDisclosureDropdown,
+ GlIcon,
+ GlTooltip,
+ DisclosureHierarchyItem,
+ },
+ props: {
+ /**
+ * A list of items in the form:
+ * ```
+ * {
+ * title: String, required
+ * icon: String, optional
+ * }
+ * ```
+ */
+ items: {
+ type: Array,
+ required: false,
+ default: () => [],
+ validator: (items) => {
+ return items.every((item) => Object.keys(item).includes('title'));
+ },
+ },
+ /**
+ * When set, displays only first and last item, and groups the rest under an ellipsis button
+ */
+ withEllipsis: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ /**
+ * When set, a tooltip displays when hovering middle ellipsis button
+ */
+ ellipsisTooltipLabel: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ itemUuid: uniqueId('disclosure-hierarchy-'),
+ };
+ },
+ computed: {
+ middleItems() {
+ return this.items.slice(1, -1).map((item) => ({ ...item, text: item.title }));
+ },
+ firstItem() {
+ return this.items[0];
+ },
+ lastItemIndex() {
+ return this.items.length - 1;
+ },
+ lastItem() {
+ return this.items[this.lastItemIndex];
+ },
+ },
+ methods: {
+ itemId(index) {
+ return `${this.itemUuid}-item-${index}`;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-relative gl-display-flex">
+ <ul class="gl-p-0 gl-m-0 gl-relative gl-list-style-none gl-display-inline-flex gl-w-85p">
+ <template v-if="withEllipsis">
+ <disclosure-hierarchy-item :item="firstItem" :item-id="itemId(0)">
+ <slot :item="firstItem" :item-id="itemId(0)"></slot>
+ </disclosure-hierarchy-item>
+ <li class="disclosure-hierarchy-item">
+ <gl-disclosure-dropdown :items="middleItems">
+ <template #toggle>
+ <button
+ id="disclosure-hierarchy-ellipsis-button"
+ class="disclosure-hierarchy-button"
+ :aria-label="ellipsisTooltipLabel"
+ >
+ <gl-icon name="ellipsis_h" class="gl-ml-3 gl-text-gray-600 gl-z-index-200" />
+ </button>
+ </template>
+ <template #list-item="{ item }">
+ <span class="gl-display-flex">
+ <gl-icon
+ v-if="item.icon"
+ :name="item.icon"
+ class="gl-mr-3 gl-vertical-align-middle gl-text-gray-600 gl-flex-shrink-0"
+ />
+ {{ item.title }}
+ </span>
+ </template>
+ </gl-disclosure-dropdown>
+ </li>
+ <gl-tooltip
+ v-if="ellipsisTooltipLabel"
+ target="disclosure-hierarchy-ellipsis-button"
+ triggers="hover"
+ >
+ {{ ellipsisTooltipLabel }}
+ </gl-tooltip>
+ <disclosure-hierarchy-item :item="lastItem" :item-id="itemId(lastItemIndex)">
+ <slot :item="lastItem" :item-id="itemId(lastItemIndex)"></slot>
+ </disclosure-hierarchy-item>
+ </template>
+ <disclosure-hierarchy-item
+ v-for="(item, index) in items"
+ v-else
+ :key="index"
+ :item="item"
+ :item-id="itemId(index)"
+ >
+ <slot :item="item" :item-id="itemId(index)"></slot>
+ </disclosure-hierarchy-item>
+ </ul>
+ </div>
+</template>