Refactor navigation component

We are anticipating necessary customizations to the app
navigation for different environments.
This refactoring will allow for a more programmatic approach.
By abstracting the navigation into a JS object we can leverage
the Vue mixin to isolate customizations while sharing a
standard template and styles.

There may be slight changes to data-test-id-* hooks.

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I0d095acfee29cfdd4ce1094b860d754f45dc6db9
diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue
index ef689d5..47ed3c1 100644
--- a/src/components/AppNavigation/AppNavigation.vue
+++ b/src/components/AppNavigation/AppNavigation.vue
@@ -3,162 +3,41 @@
     <div class="nav-container" :class="{ open: isNavigationOpen }">
       <nav ref="nav" :aria-label="$t('appNavigation.primaryNavigation')">
         <b-nav vertical class="mb-4">
-          <b-nav-item to="/" data-test-id="nav-container-overview">
-            <icon-overview />
-            {{ $t('appNavigation.overview') }}
-          </b-nav-item>
-
-          <li class="nav-item">
-            <b-button
-              v-b-toggle.health-menu
-              variant="link"
-              data-test-id="nav-button-health"
+          <template v-for="(navItem, index) in navigationItems">
+            <!-- Navigation items with no children -->
+            <b-nav-item
+              v-if="!navItem.children"
+              :key="index"
+              :to="navItem.route"
+              :data-test-id="`nav-item-${navItem.id}`"
             >
-              <icon-health />
-              {{ $t('appNavigation.health') }}
-              <icon-expand class="icon-expand" />
-            </b-button>
-            <b-collapse id="health-menu" tag="ul" class="nav-item__nav">
-              <b-nav-item
-                to="/health/event-logs"
-                data-test-id="nav-container-event-logs"
-              >
-                {{ $t('appNavigation.eventLogs') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/health/hardware-status"
-                data-test-id="nav-container-hardware-status"
-              >
-                {{ $t('appNavigation.hardwareStatus') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/health/sensors"
-                data-test-id="nav-container-sensors"
-              >
-                {{ $t('appNavigation.sensors') }}
-              </b-nav-item>
-            </b-collapse>
-          </li>
+              <component :is="navItem.icon" />
+              {{ navItem.label }}
+            </b-nav-item>
 
-          <li class="nav-item">
-            <b-button
-              v-b-toggle.control-menu
-              variant="link"
-              data-test-id="nav-button-control"
-            >
-              <icon-control />
-              {{ $t('appNavigation.control') }}
-              <icon-expand class="icon-expand" />
-            </b-button>
-            <b-collapse id="control-menu" tag="ul" class="nav-item__nav">
-              <b-nav-item to="/control/kvm" data-test-id="nav-container-kvm">
-                {{ $t('appNavigation.kvm') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/control/manage-power-usage"
-                data-test-id="nav-container-managePowerUsage"
+            <!-- Navigation items with children -->
+            <li v-else :key="index" class="nav-item">
+              <b-button
+                v-b-toggle="`${navItem.id}`"
+                variant="link"
+                :data-test-id="`nav-button-${navItem.id}`"
               >
-                {{ $t('appNavigation.managePowerUsage') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/control/reboot-bmc"
-                data-test-id="nav-container-rebootBmc"
-              >
-                {{ $t('appNavigation.rebootBmc') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/control/serial-over-lan"
-                data-test-id="nav-container-sol"
-              >
-                {{ $t('appNavigation.serialOverLan') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/control/server-led"
-                data-test-id="nav-container-serverLed"
-              >
-                {{ $t('appNavigation.serverLed') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/control/server-power-operations"
-                data-test-id="nav-container-serverPowerOperations"
-              >
-                {{ $t('appNavigation.serverPowerOperations') }}
-              </b-nav-item>
-              <b-nav-item to="/control/virtual-media">
-                {{ $t('appNavigation.virtualMedia') }}
-              </b-nav-item>
-            </b-collapse>
-          </li>
-
-          <li class="nav-item">
-            <b-button
-              v-b-toggle.configuration-menu
-              variant="link"
-              data-test-id="nav-button-configuration"
-            >
-              <icon-configuration />
-              {{ $t('appNavigation.configuration') }}
-              <icon-expand class="icon-expand" />
-            </b-button>
-            <b-collapse id="configuration-menu" tag="ul" class="nav-item__nav">
-              <b-nav-item
-                to="/configuration/date-time-settings"
-                data-test-id="nav-container-dateTimeSettings"
-              >
-                {{ $t('appNavigation.dateTimeSettings') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/configuration/firmware"
-                data-test-id="nav-container-firmware"
-              >
-                {{ $t('appNavigation.firmware') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/configuration/network-settings"
-                data-test-id="nav-container-networkSettings"
-              >
-                {{ $t('appNavigation.networkSettings') }}
-              </b-nav-item>
-              <b-nav-item
-                href="javascript:void(0)"
-                data-test-id="nav-container-snmp"
-              >
-                {{ $t('appNavigation.snmpSettings') }}
-              </b-nav-item>
-            </b-collapse>
-          </li>
-
-          <li class="nav-item">
-            <b-button
-              v-b-toggle.access-control-menu
-              variant="link"
-              data-test-id="nav-button-accessControl"
-            >
-              <icon-access-control />
-              {{ $t('appNavigation.accessControl') }}
-              <icon-expand class="icon-expand" />
-            </b-button>
-            <b-collapse id="access-control-menu" tag="ul" class="nav-item__nav">
-              <b-nav-item
-                to="/access-control/ldap"
-                data-test-id="nav-container-ldap"
-              >
-                {{ $t('appNavigation.ldap') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/access-control/local-user-management"
-                data-test-id="nav-container-localUserManagement"
-              >
-                {{ $t('appNavigation.localUserManagement') }}
-              </b-nav-item>
-              <b-nav-item
-                to="/access-control/ssl-certificates"
-                data-test-id="nav-container-sslCertificates"
-              >
-                {{ $t('appNavigation.sslCertificates') }}
-              </b-nav-item>
-            </b-collapse>
-          </li>
+                <component :is="navItem.icon" />
+                {{ navItem.label }}
+                <icon-expand class="icon-expand" />
+              </b-button>
+              <b-collapse :id="navItem.id" tag="ul" class="nav-item__nav">
+                <b-nav-item
+                  v-for="(subNavItem, i) of navItem.children"
+                  :key="i"
+                  :to="subNavItem.route"
+                  :data-test-id="`nav-item-${subNavItem.id}`"
+                >
+                  {{ subNavItem.label }}
+                </b-nav-item>
+              </b-collapse>
+            </li>
+          </template>
         </b-nav>
       </nav>
     </div>
@@ -174,23 +53,11 @@
 </template>
 
 <script>
-import IconAnalytics from '@carbon/icons-vue/es/analytics/16';
-import IconDataCheck from '@carbon/icons-vue/es/data--check/16';
-import IconSettingsAdjust from '@carbon/icons-vue/es/settings--adjust/16';
-import IconSettings from '@carbon/icons-vue/es/settings/16';
-import IconPassword from '@carbon/icons-vue/es/password/16';
-import IconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+import AppNavigationMixin from './AppNavigationMixin';
 
 export default {
   name: 'AppNavigation',
-  components: {
-    iconOverview: IconAnalytics,
-    iconHealth: IconDataCheck,
-    iconControl: IconSettingsAdjust,
-    iconConfiguration: IconSettings,
-    iconAccessControl: IconPassword,
-    iconExpand: IconChevronUp
-  },
+  mixins: [AppNavigationMixin],
   data() {
     return {
       isNavigationOpen: false