blob: eb8c2c64a99be201ffaf8d2c25432d6f39c8cb55 [file] [log] [blame]
Derick Montaguea2988f42020-01-17 13:46:30 -06001<template>
Yoshie Muranaka74f86872020-02-10 12:28:37 -08002 <div>
3 <div class="nav-container" :class="{ open: isNavigationOpen }">
Derick Montague68592032020-04-04 14:02:34 -05004 <nav ref="nav" :aria-label="$t('appNavigation.primaryNavigation')">
Yoshie Muranaka7d044352020-07-24 10:45:14 -07005 <b-nav vertical class="mb-4">
Ed Tanous9c729792024-03-23 14:56:34 -07006 <template v-for="navItem in navigationItems">
Yoshie Muranakad329ec82020-08-11 18:24:59 -07007 <!-- Navigation items with no children -->
8 <b-nav-item
9 v-if="!navItem.children"
Ed Tanous9c729792024-03-23 14:56:34 -070010 :key="navItem.index"
Yoshie Muranakad329ec82020-08-11 18:24:59 -070011 :to="navItem.route"
12 :data-test-id="`nav-item-${navItem.id}`"
Derick Montague2d589a72020-07-23 17:43:12 -050013 >
Yoshie Muranakad329ec82020-08-11 18:24:59 -070014 <component :is="navItem.icon" />
15 {{ navItem.label }}
16 </b-nav-item>
Derick Montague42c19892020-01-17 16:10:34 -060017
Yoshie Muranakad329ec82020-08-11 18:24:59 -070018 <!-- Navigation items with children -->
Ed Tanous9c729792024-03-23 14:56:34 -070019 <li v-else :key="navItem.index" class="nav-item">
Yoshie Muranakad329ec82020-08-11 18:24:59 -070020 <b-button
21 v-b-toggle="`${navItem.id}`"
22 variant="link"
23 :data-test-id="`nav-button-${navItem.id}`"
Derick Montague2d589a72020-07-23 17:43:12 -050024 >
Yoshie Muranakad329ec82020-08-11 18:24:59 -070025 <component :is="navItem.icon" />
26 {{ navItem.label }}
27 <icon-expand class="icon-expand" />
28 </b-button>
29 <b-collapse :id="navItem.id" tag="ul" class="nav-item__nav">
Sukanya Pandeyfba4d622020-12-29 13:31:19 +053030 <li class="nav-item">
31 <router-link
Damian Celicoaeb19812022-11-24 02:00:53 +010032 v-for="(subNavItem, i) of filteredNavItem(navItem.children)"
Sukanya Pandeyfba4d622020-12-29 13:31:19 +053033 :key="i"
34 :to="subNavItem.route"
35 :data-test-id="`nav-item-${subNavItem.id}`"
36 class="nav-link"
37 >
38 {{ subNavItem.label }}
39 </router-link>
40 </li>
Yoshie Muranakad329ec82020-08-11 18:24:59 -070041 </b-collapse>
42 </li>
43 </template>
Yoshie Muranaka74f86872020-02-10 12:28:37 -080044 </b-nav>
45 </nav>
46 </div>
47 <transition name="fade">
48 <div
49 v-if="isNavigationOpen"
Derick Montaguead2ceb62020-04-24 18:11:04 -050050 id="nav-overlay"
Yoshie Muranaka74f86872020-02-10 12:28:37 -080051 class="nav-overlay"
52 @click="toggleIsOpen"
53 ></div>
54 </transition>
55 </div>
Derick Montaguea2988f42020-01-17 13:46:30 -060056</template>
57
58<script>
Yoshie Muranaka8263d852020-10-16 07:58:06 -070059//Do not change Mixin import.
60//Exact match alias set to support
61//dotenv customizations.
Yoshie Muranakad329ec82020-08-11 18:24:59 -070062import AppNavigationMixin from './AppNavigationMixin';
Ed Tanousdbd37e02024-03-23 14:56:34 -070063import { useI18n } from 'vue-i18n';
Derick Montaguea2988f42020-01-17 13:46:30 -060064
65export default {
Derick Montaguee2fd1562019-12-20 13:26:53 -060066 name: 'AppNavigation',
Yoshie Muranakad329ec82020-08-11 18:24:59 -070067 mixins: [AppNavigationMixin],
Yoshie Muranaka74f86872020-02-10 12:28:37 -080068 data() {
69 return {
Ed Tanousdbd37e02024-03-23 14:56:34 -070070 $t: useI18n().t,
Derick Montague602e98a2020-10-21 16:20:00 -050071 isNavigationOpen: false,
Damian Celicoaeb19812022-11-24 02:00:53 +010072 currentUserRole: null,
Yoshie Muranaka74f86872020-02-10 12:28:37 -080073 };
74 },
75 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -050076 $route: function () {
Yoshie Muranaka74f86872020-02-10 12:28:37 -080077 this.isNavigationOpen = false;
78 },
Derick Montague602e98a2020-10-21 16:20:00 -050079 isNavigationOpen: function (isNavigationOpen) {
Sukanya Pandeyedb8a772020-10-29 11:33:42 +053080 this.$root.$emit('change-is-navigation-open', isNavigationOpen);
Derick Montague602e98a2020-10-21 16:20:00 -050081 },
Yoshie Muranaka74f86872020-02-10 12:28:37 -080082 },
83 mounted() {
Damian Celicoaeb19812022-11-24 02:00:53 +010084 this.getPrivilege();
Sukanya Pandeyedb8a772020-10-29 11:33:42 +053085 this.$root.$on('toggle-navigation', () => this.toggleIsOpen());
Yoshie Muranaka74f86872020-02-10 12:28:37 -080086 },
87 methods: {
88 toggleIsOpen() {
89 this.isNavigationOpen = !this.isNavigationOpen;
Derick Montague602e98a2020-10-21 16:20:00 -050090 },
Damian Celicoaeb19812022-11-24 02:00:53 +010091 getPrivilege() {
92 this.currentUserRole = this.$store?.getters['global/userPrivilege'];
93 },
94 filteredNavItem(navItem) {
95 if (this.currentUserRole) {
96 return navItem.filter(({ exclusiveToRoles }) => {
97 if (!exclusiveToRoles?.length) return true;
98 return exclusiveToRoles.includes(this.currentUserRole);
99 });
100 } else return navItem;
101 },
Derick Montague602e98a2020-10-21 16:20:00 -0500102 },
Derick Montaguea2988f42020-01-17 13:46:30 -0600103};
104</script>
Derick Montague42c19892020-01-17 16:10:34 -0600105
Ed Tanous9c729792024-03-23 14:56:34 -0700106<style lang="scss" scoped>
107@import '@/assets/styles/bmc/helpers/_index.scss';
108@import '@/assets/styles/bootstrap/_helpers.scss';
109
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800110svg {
Derick Montague66f903f2020-02-28 11:22:31 -0600111 fill: currentColor;
112 height: 1.2rem;
113 width: 1.2rem;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800114 margin-left: 0 !important; //!important overriding button specificity
115 vertical-align: text-bottom;
116 &:not(.icon-expand) {
117 margin-right: $spacer;
118 }
119}
120
121.nav {
SurenNeware057232b2020-06-08 20:53:26 +0530122 padding-top: $spacer / 4;
123 @include media-breakpoint-up($responsive-layout-bp) {
124 padding-top: $spacer;
125 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800126}
127
128.nav-item__nav {
Derick Montague42c19892020-01-17 16:10:34 -0600129 list-style: none;
130 padding-left: 0;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800131 margin-left: 0;
132
Yoshie Muranaka85358ed2020-05-18 10:05:36 -0700133 .nav-item {
134 outline: none;
135 }
136
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800137 .nav-link {
138 padding-left: $spacer * 4;
Yoshie Muranaka85358ed2020-05-18 10:05:36 -0700139 outline: none;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800140
141 &:not(.nav-link--current) {
142 font-weight: normal;
143 }
144 }
145}
146
147.btn-link {
Dixsie Wolmers30f11f82020-11-10 16:07:56 -0600148 display: inline-block;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800149 width: 100%;
150 text-align: left;
151 text-decoration: none !important;
152 border-radius: 0;
153
154 &.collapsed {
155 .icon-expand {
156 transform: rotate(180deg);
157 }
158 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800159}
160
161.icon-expand {
162 float: right;
163 margin-top: $spacer / 4;
164}
165
166.btn-link,
167.nav-link {
168 position: relative;
169 font-weight: $headings-font-weight;
170 padding-left: $spacer; // defining consistent padding for links and buttons
171 padding-right: $spacer;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700172 color: theme-color('secondary');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800173
174 &:hover {
SurenNeware1f8117f2020-09-22 19:28:56 +0530175 background-color: theme-color-level(dark, -10.5);
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700176 color: theme-color('dark');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800177 }
Yoshie Muranaka9f5cea82020-02-04 09:30:00 -0800178
179 &:focus {
SurenNeware1f8117f2020-09-22 19:28:56 +0530180 background-color: theme-color-level(light, 0);
181 box-shadow: inset 0 0 0 2px theme-color('primary');
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700182 color: theme-color('dark');
Derick Montague59569d82020-10-26 15:17:31 -0500183 outline: 0;
Yoshie Muranaka9f5cea82020-02-04 09:30:00 -0800184 }
SurenNeware1f8117f2020-09-22 19:28:56 +0530185
186 &:active {
Derick Montague59569d82020-10-26 15:17:31 -0500187 background-color: theme-color('secondary');
SurenNeware1f8117f2020-09-22 19:28:56 +0530188 color: $white;
189 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800190}
191
SurenNeware1f8117f2020-09-22 19:28:56 +0530192.nav-link--current {
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800193 font-weight: $headings-font-weight;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700194 background-color: theme-color('secondary');
195 color: theme-color('light');
Derick Montague66f903f2020-02-28 11:22:31 -0600196 cursor: default;
SurenNeware1f8117f2020-09-22 19:28:56 +0530197 box-shadow: none;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800198
199 &::before {
200 content: '';
201 position: absolute;
202 top: 0;
203 bottom: 0;
204 left: 0;
205 width: 4px;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700206 background-color: theme-color('primary');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800207 }
Derick Montague59569d82020-10-26 15:17:31 -0500208
209 &:hover,
SurenNeware1f8117f2020-09-22 19:28:56 +0530210 &:focus {
Derick Montague59569d82020-10-26 15:17:31 -0500211 background-color: theme-color('secondary');
212 color: theme-color('light');
SurenNeware1f8117f2020-09-22 19:28:56 +0530213 }
214}
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800215
216.nav-container {
217 position: fixed;
218 width: $navigation-width;
219 top: $header-height;
220 bottom: 0;
221 left: 0;
222 z-index: $zindex-fixed;
223 overflow-y: auto;
Derick Montague59569d82020-10-26 15:17:31 -0500224 background-color: theme-color('light');
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800225 transform: translateX(-$navigation-width);
226 transition: transform $exit-easing--productive $duration--moderate-02;
Derick Montague59569d82020-10-26 15:17:31 -0500227 border-right: 1px solid theme-color-level('light', 2.85);
228
SurenNeware057232b2020-06-08 20:53:26 +0530229 @include media-breakpoint-down(md) {
230 z-index: $zindex-fixed + 2;
231 }
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800232
Derick Montague74466b82020-06-28 10:17:32 -0500233 &.open,
234 &:focus-within {
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800235 transform: translateX(0);
236 transition-timing-function: $entrance-easing--productive;
237 }
238
239 @include media-breakpoint-up($responsive-layout-bp) {
240 transition-duration: $duration--fast-01;
241 transform: translateX(0);
242 }
243}
244
245.nav-overlay {
246 position: fixed;
247 top: $header-height;
248 bottom: 0;
249 left: 0;
250 right: 0;
SurenNeware057232b2020-06-08 20:53:26 +0530251 z-index: $zindex-fixed + 1;
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800252 background-color: $black;
253 opacity: 0.5;
254
255 &.fade-enter-active {
256 transition: opacity $duration--moderate-02 $entrance-easing--productive;
257 }
258
259 &.fade-leave-active {
260 transition: opacity $duration--fast-02 $exit-easing--productive;
261 }
262
SurenNeware151dd242020-11-10 20:15:05 +0530263 &.fade-enter, // Remove this vue2 based only class when switching to vue3
264 &.fade-enter-from, // This is vue3 based only class modified from 'fade-enter'
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800265 &.fade-leave-to {
266 opacity: 0;
267 }
268
269 @include media-breakpoint-up($responsive-layout-bp) {
270 display: none;
271 }
272}
Derick Montague42c19892020-01-17 16:10:34 -0600273</style>