1<template>
2  <div>
3    <div class="nav-container" :class="{ open: isNavigationOpen }">
4      <nav ref="nav">
5        <b-nav vertical>
6          <b-nav-item to="/">
7            <icon-overview />
8            {{ $t('appNavigation.overview') }}
9          </b-nav-item>
10
11          <li class="nav-item">
12            <b-button v-b-toggle.health-menu variant="link">
13              <icon-health />
14              {{ $t('appNavigation.health') }}
15              <icon-expand class="icon-expand" />
16            </b-button>
17            <b-collapse id="health-menu" tag="ul" class="nav-item__nav">
18              <b-nav-item href="javascript:void(0)">
19                {{ $t('appNavigation.eventLog') }}
20              </b-nav-item>
21              <b-nav-item href="javascript:void(0)">
22                {{ $t('appNavigation.hardwareStatus') }}
23              </b-nav-item>
24              <b-nav-item href="javascript:void(0)">
25                {{ $t('appNavigation.sensors') }}
26              </b-nav-item>
27            </b-collapse>
28          </li>
29
30          <li class="nav-item">
31            <b-button v-b-toggle.control-menu variant="link">
32              <icon-control />
33              {{ $t('appNavigation.control') }}
34              <icon-expand class="icon-expand" />
35            </b-button>
36            <b-collapse id="control-menu" tag="ul" class="nav-item__nav">
37              <b-nav-item href="javascript:void(0)">
38                {{ $t('appNavigation.managePowerUsage') }}
39              </b-nav-item>
40              <b-nav-item to="/control/reboot-bmc">
41                {{ $t('appNavigation.rebootBmc') }}
42              </b-nav-item>
43              <b-nav-item href="javascript:void(0)">
44                {{ $t('appNavigation.serverLed') }}
45              </b-nav-item>
46              <b-nav-item to="/control/server-power-operations">
47                {{ $t('appNavigation.serverPowerOperations') }}
48              </b-nav-item>
49            </b-collapse>
50          </li>
51
52          <li class="nav-item">
53            <b-button v-b-toggle.configuration-menu variant="link">
54              <icon-configuration />
55              {{ $t('appNavigation.configuration') }}
56              <icon-expand class="icon-expand" />
57            </b-button>
58            <b-collapse id="configuration-menu" tag="ul" class="nav-item__nav">
59              <b-nav-item href="javascript:void(0)">
60                {{ $t('appNavigation.firmware') }}
61              </b-nav-item>
62              <b-nav-item href="javascript:void(0)">
63                {{ $t('appNavigation.networkSettings') }}
64              </b-nav-item>
65              <b-nav-item href="javascript:void(0)">
66                {{ $t('appNavigation.snmpSettings') }}
67              </b-nav-item>
68            </b-collapse>
69          </li>
70
71          <li class="nav-item">
72            <b-button v-b-toggle.access-control-menu variant="link">
73              <icon-access-control />
74              {{ $t('appNavigation.accessControl') }}
75              <icon-expand class="icon-expand" />
76            </b-button>
77            <b-collapse id="access-control-menu" tag="ul" class="nav-item__nav">
78              <b-nav-item href="javascript:void(0)">
79                {{ $t('appNavigation.ldap') }}
80              </b-nav-item>
81              <b-nav-item to="/access-control/local-user-management">
82                {{ $t('appNavigation.localUserManagement') }}
83              </b-nav-item>
84              <b-nav-item href="javascript:void(0)">
85                {{ $t('appNavigation.sslCertificates') }}
86              </b-nav-item>
87            </b-collapse>
88          </li>
89        </b-nav>
90      </nav>
91    </div>
92    <transition name="fade">
93      <div
94        v-if="isNavigationOpen"
95        class="nav-overlay"
96        @click="toggleIsOpen"
97      ></div>
98    </transition>
99  </div>
100</template>
101
102<script>
103import IconAnalytics from '@carbon/icons-vue/es/analytics/16';
104import IconDataCheck from '@carbon/icons-vue/es/data--check/16';
105import IconSettingsAdjust from '@carbon/icons-vue/es/settings--adjust/16';
106import IconSettings from '@carbon/icons-vue/es/settings/16';
107import IconPassword from '@carbon/icons-vue/es/password/16';
108import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
109
110export default {
111  name: 'AppNavigation',
112  components: {
113    iconOverview: IconAnalytics,
114    iconHealth: IconDataCheck,
115    iconControl: IconSettingsAdjust,
116    iconConfiguration: IconSettings,
117    iconAccessControl: IconPassword,
118    iconExpand: IconChevronUp
119  },
120  data() {
121    return {
122      isNavigationOpen: false
123    };
124  },
125  watch: {
126    $route: function() {
127      this.isNavigationOpen = false;
128    },
129    isNavigationOpen: function(isNavigationOpen) {
130      this.$root.$emit('change:isNavigationOpen', isNavigationOpen);
131    }
132  },
133  mounted() {
134    this.$root.$on('toggle:navigation', () => this.toggleIsOpen());
135  },
136  methods: {
137    toggleIsOpen() {
138      this.isNavigationOpen = !this.isNavigationOpen;
139    }
140  }
141};
142</script>
143
144<style scoped lang="scss">
145svg {
146  fill: currentColor;
147  height: 1.2rem;
148  width: 1.2rem;
149  margin-left: 0 !important; //!important overriding button specificity
150  vertical-align: text-bottom;
151  &:not(.icon-expand) {
152    margin-right: $spacer;
153  }
154}
155
156.nav {
157  padding-top: $spacer;
158}
159
160.nav-item__nav {
161  list-style: none;
162  padding-left: 0;
163  margin-left: 0;
164
165  .nav-link {
166    padding-left: $spacer * 4;
167
168    &:not(.nav-link--current) {
169      font-weight: normal;
170    }
171  }
172}
173
174.btn-link {
175  width: 100%;
176  text-align: left;
177  text-decoration: none !important;
178  border-radius: 0;
179
180  &.collapsed {
181    .icon-expand {
182      transform: rotate(180deg);
183    }
184  }
185}
186
187.icon-expand {
188  float: right;
189  margin-top: $spacer / 4;
190}
191
192.btn-link,
193.nav-link {
194  position: relative;
195  font-weight: $headings-font-weight;
196  padding-left: $spacer; // defining consistent padding for links and buttons
197  padding-right: $spacer;
198  color: $secondary;
199
200  &:hover {
201    background-color: $primary-nav-hover;
202    color: $dark;
203  }
204
205  &:focus {
206    box-shadow: $btn-focus-box-shadow;
207    color: $dark;
208  }
209}
210
211.nav-link--current,
212.nav-link--current:hover,
213.nav-link--current:focus {
214  font-weight: $headings-font-weight;
215  background-color: $secondary;
216  color: $light;
217  cursor: default;
218
219  &::before {
220    content: '';
221    position: absolute;
222    top: 0;
223    bottom: 0;
224    left: 0;
225    width: 4px;
226    background-color: $primary;
227  }
228}
229
230.nav-container {
231  position: fixed;
232  width: $navigation-width;
233  top: $header-height;
234  bottom: 0;
235  left: 0;
236  z-index: $zindex-fixed;
237  overflow-y: auto;
238  background-color: $container-bgd;
239  transform: translateX(-$navigation-width);
240  transition: transform $exit-easing--productive $duration--moderate-02;
241
242  &.open {
243    transform: translateX(0);
244    transition-timing-function: $entrance-easing--productive;
245  }
246
247  @include media-breakpoint-up($responsive-layout-bp) {
248    transition-duration: $duration--fast-01;
249    transform: translateX(0);
250  }
251}
252
253.nav-overlay {
254  position: fixed;
255  top: $header-height;
256  bottom: 0;
257  left: 0;
258  right: 0;
259  z-index: $zindex-fixed - 1;
260  background-color: $black;
261  opacity: 0.5;
262
263  &.fade-enter-active {
264    transition: opacity $duration--moderate-02 $entrance-easing--productive;
265  }
266
267  &.fade-leave-active {
268    transition: opacity $duration--fast-02 $exit-easing--productive;
269  }
270
271  &.fade-enter,
272  &.fade-leave-to {
273    opacity: 0;
274  }
275
276  @include media-breakpoint-up($responsive-layout-bp) {
277    display: none;
278  }
279}
280</style>
281