Welcome to mirror list, hosted at ThFree Co, Russian Federation.

pinned_section.vue « components « super_sidebar « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4dee6a3baf637467d9d67d0fe7a7e671ffe16bb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<script>
import Draggable from 'vuedraggable';
import { s__ } from '~/locale';
import { setCookie, getCookie } from '~/lib/utils/common_utils';
import { SIDEBAR_PINS_EXPANDED_COOKIE, SIDEBAR_COOKIE_EXPIRATION } from '../constants';
import MenuSection from './menu_section.vue';
import NavItem from './nav_item.vue';

const AMBIGUOUS_SETTINGS = {
  ci_cd: s__('Navigation|CI/CD settings'),
  merge_request_settings: s__('Navigation|Merge requests settings'),
  monitor: s__('Navigation|Monitor settings'),
  repository: s__('Navigation|Repository settings'),
};

export default {
  i18n: {
    pinned: s__('Navigation|Pinned'),
    emptyHint: s__('Navigation|Your pinned items appear here.'),
  },
  name: 'PinnedSection',
  components: {
    Draggable,
    MenuSection,
    NavItem,
  },
  props: {
    items: {
      type: Array,
      required: false,
      default: () => [],
    },
    hasFlyout: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  data() {
    return {
      expanded: getCookie(SIDEBAR_PINS_EXPANDED_COOKIE) !== 'false',
      draggableItems: this.renameSettings(this.items),
    };
  },
  computed: {
    isActive() {
      return this.items.some((item) => item.is_active);
    },
    sectionItem() {
      return {
        title: this.$options.i18n.pinned,
        icon: 'thumbtack',
        is_active: this.isActive,
        items: this.draggableItems,
      };
    },
    itemIds() {
      return this.draggableItems.map((item) => item.id);
    },
  },
  watch: {
    expanded(newExpanded) {
      setCookie(SIDEBAR_PINS_EXPANDED_COOKIE, newExpanded, {
        expires: SIDEBAR_COOKIE_EXPIRATION,
      });
    },
    items(newItems) {
      this.draggableItems = this.renameSettings(newItems);
    },
  },
  methods: {
    handleDrag(event) {
      if (event.oldIndex === event.newIndex) return;
      this.$emit(
        'pin-reorder',
        this.items[event.oldIndex].id,
        this.items[event.newIndex].id,
        event.oldIndex < event.newIndex,
      );
    },
    renameSettings(items) {
      return items.map((i) => {
        const title = AMBIGUOUS_SETTINGS[i.id] || i.title;
        return { ...i, title };
      });
    },
    onPinRemove(itemId, itemTitle) {
      this.$emit('pin-remove', itemId, itemTitle);
    },
  },
};
</script>

<template>
  <menu-section
    :item="sectionItem"
    :expanded="expanded"
    :has-flyout="hasFlyout"
    @collapse-toggle="expanded = !expanded"
    @pin-remove="onPinRemove"
  >
    <draggable
      v-if="items.length > 0"
      v-model="draggableItems"
      class="gl-p-0 gl-m-0 gl-list-style-none"
      data-testid="pinned-nav-items"
      handle=".js-draggable-icon"
      tag="ul"
      @end="handleDrag"
    >
      <nav-item
        v-for="item of draggableItems"
        :key="item.id"
        :item="item"
        is-in-pinned-section
        @pin-remove="onPinRemove(item.id, item.title)"
      />
    </draggable>
    <li
      v-else
      class="gl-text-secondary gl-font-sm gl-py-3 super-sidebar-mix-blend-mode"
      style="margin-left: 2.5rem"
    >
      {{ $options.i18n.emptyHint }}
    </li>
  </menu-section>
</template>