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
|
<script>
import { cloneDeep } from 'lodash';
import { FREQUENT_ITEMS_PROJECTS, FREQUENT_ITEMS_GROUPS } from '~/frequent_items/constants';
import KeepAliveSlots from '~/vue_shared/components/keep_alive_slots.vue';
import TopNavContainerView from './top_nav_container_view.vue';
import TopNavMenuSections from './top_nav_menu_sections.vue';
export default {
components: {
KeepAliveSlots,
TopNavContainerView,
TopNavMenuSections,
},
props: {
primary: {
type: Array,
required: false,
default: () => [],
},
secondary: {
type: Array,
required: false,
default: () => [],
},
views: {
type: Object,
required: false,
default: () => ({}),
},
},
data() {
// It's expected that primary & secondary never change, so these are treated as "init" props.
// We need to clone so that we can mutate the data without mutating the props
const menuSections = [
{ id: 'primary', menuItems: cloneDeep(this.primary) },
{ id: 'secondary', menuItems: cloneDeep(this.secondary) },
].filter((x) => x.menuItems?.length);
return {
menuSections,
};
},
computed: {
allMenuItems() {
return this.menuSections.flatMap((x) => x.menuItems);
},
activeView() {
const active = this.allMenuItems.find((x) => x.active);
return active?.view;
},
menuClass() {
if (!this.activeView) {
return 'gl-w-full';
}
return '';
},
},
methods: {
onMenuItemClick({ id }) {
this.allMenuItems.forEach((menuItem) => {
this.$set(menuItem, 'active', id === menuItem.id);
});
},
},
FREQUENT_ITEMS_PROJECTS,
FREQUENT_ITEMS_GROUPS,
};
</script>
<template>
<div class="gl-display-flex gl-align-items-stretch">
<div
class="gl-w-grid-size-30 gl-flex-shrink-0 gl-bg-gray-10 gl-p-3"
:class="menuClass"
data-testid="menu-sidebar"
>
<top-nav-menu-sections
:sections="menuSections"
:is-primary-section="true"
@menu-item-click="onMenuItemClick"
/>
</div>
<keep-alive-slots
v-show="activeView"
:slot-key="activeView"
class="gl-w-grid-size-40 gl-overflow-hidden gl-p-3"
data-testid="menu-subview"
data-qa-selector="menu_subview_container"
>
<template #projects>
<top-nav-container-view
:frequent-items-dropdown-type="$options.FREQUENT_ITEMS_PROJECTS.namespace"
:frequent-items-vuex-module="$options.FREQUENT_ITEMS_PROJECTS.vuexModule"
v-bind="views.projects"
/>
</template>
<template #groups>
<top-nav-container-view
:frequent-items-dropdown-type="$options.FREQUENT_ITEMS_GROUPS.namespace"
:frequent-items-vuex-module="$options.FREQUENT_ITEMS_GROUPS.vuexModule"
v-bind="views.groups"
/>
</template>
</keep-alive-slots>
</div>
</template>
|