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