Network settings redesign - interface settings

First commit of the network settings redesign:

- Adds the global network settings section for DHCP settings
- Adds read only hostname, FQDN and MAC address,
modal to edit each will be done seperately
- Removes interface specific sections to refactor in next commit
- Adds tab component to display ethernet data by interface
- Ability  to edit, delete and add ipv4 addresses and DNS will
be done in separate commit

Signed-off-by: Dixsie Wolmers <dixsie@ibm.com>
Change-Id: Ibb1db6894ee697fec9e6ea1b8312d041c61faaad
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 7e35d45..3bfc4a8 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -630,38 +630,43 @@
   },
   "pageNetwork": {
     "dhcp": "DHCP",
-    "ipv4": "IPV4",
-    "ipv4Configuration": "IPV4 configuration",
-    "ipv4Helper": "An IP address must be available to enable DHCP or Static configuration",
-    "interface": "Interface",
-    "pageDescription": "Configure network settings for the BMC",
-    "static": "Static",
+    "domainName": "domain name",
+    "dns": "DNS server",
+    "fqdn": "FQDN",
+    "hostname": "Hostname",
+    "interfaceSection": "Interface settings",
+    "ipv4": "IPv4",
+    "ipv4Addresses": "IPv4 addresses",
+    "ipv6": "IPv6",
+    "linkStatus": "Link status",
+    "macAddress": "MAC address",
+    "networkSettings": "Network settings",
+    "ntp": "NTP server",
+    "pageDescription": "Configure BMC network settings",
+    "useDns": "Use DNS servers",
+    "useDomainName": "Use domain name",
+    "useNtp": "Use NTP servers",
+    "speed": "Speed (mbps)",
     "staticDns": "Static DNS",
-    "system": "System",
-    "form": {
-      "defaultGateway": "Default gateway",
-      "hostname": "Hostname",
-      "macAddress": "MAC address",
-      "networkInterface": "Network interface"
+    "modal": {
+      "ipAddress": "IP address",
+      "gateway": "Gateway",
+      "subnetMask": "Subnet mask"
     },
     "table": {
-      "addDns": "Add DNS server",
-      "addStaticIpv4Address": "Add static IP",
-      "deleteDhcpIpv4": "Delete IPv4 row",
-      "deleteDns": "Delete DNS row",
-      "deleteStaticIpv4": "Delete IPv4 row",
-      "dhcpIpv4AddressRow": "DHCP IPv4 address",
-      "dhcpIpv4SubnetRow": "DHCP IPV4 subnet",
+      "addIpv4Address": "Add static IPv4 address",
+      "addressOrigin": "Address origin",
+      "deleteDns": "Edit DNS address",
+      "deleteIpv4": "Edit IPv4 address",
+      "editDns": "Edit DNS address",
+      "editIpv4": "Edit IPv4 address",
+      "gateway": "Gateway",
       "ipAddress": "IP address",
-      "staticDnsRow": "Static DNS address",
-      "staticIpv4AddressRow": "Static IPv4 address",
-      "staticIpv4SubnetRow": "Static IPV4 subnet",
       "subnet": "Subnet mask"
     },
     "toast": {
-      "errorSaveDhcpSettings": "Error enabling DHCP configuration.",
-      "errorSaveNetworkSettings": "Error saving network settings.",
-      "successSaveNetworkSettings": "Successfully saved network settings."
+      "errorSaveNetworkSettings": "Error updating %{setting} settings.",
+      "successSaveNetworkSettings": "Successfully updated %{setting} settings."
     }
   },
   "pagePageNotFound": {
diff --git a/src/main.js b/src/main.js
index 8fcb808..0aae716 100644
--- a/src/main.js
+++ b/src/main.js
@@ -34,6 +34,7 @@
   PaginationPlugin,
   ProgressPlugin,
   TablePlugin,
+  TabsPlugin,
   ToastPlugin,
   TooltipPlugin,
 } from 'bootstrap-vue';
@@ -123,6 +124,7 @@
 Vue.use(PaginationPlugin);
 Vue.use(ProgressPlugin);
 Vue.use(TablePlugin);
+Vue.use(TabsPlugin);
 Vue.use(ToastPlugin);
 Vue.use(TooltipPlugin);
 Vue.use(Vuelidate);
diff --git a/src/store/modules/Settings/NetworkStore.js b/src/store/modules/Settings/NetworkStore.js
index 65a83b4..5b95cb0 100644
--- a/src/store/modules/Settings/NetworkStore.js
+++ b/src/store/modules/Settings/NetworkStore.js
@@ -1,43 +1,42 @@
 import api from '@/store/api';
 import i18n from '@/i18n';
-import { find, remove } from 'lodash';
 
 const NetworkStore = {
   namespaced: true,
   state: {
-    defaultGateway: '',
     ethernetData: [],
-    interfaceOptions: [],
+    firstInterfaceId: '', //used for setting global DHCP settings
     globalNetworkSettings: [],
   },
   getters: {
-    defaultGateway: (state) => state.defaultGateway,
     ethernetData: (state) => state.ethernetData,
-    interfaceOptions: (state) => state.interfaceOptions,
+    firstInterfaceId: (state) => state.firstInterfaceId,
     globalNetworkSettings: (state) => state.globalNetworkSettings,
   },
   mutations: {
-    setDefaultGateway: (state, defaultGateway) =>
-      (state.defaultGateway = defaultGateway),
     setEthernetData: (state, ethernetData) =>
       (state.ethernetData = ethernetData),
-    setInterfaceOptions: (state, interfaceOptions) =>
-      (state.interfaceOptions = interfaceOptions),
+    setFirstInterfaceId: (state, firstInterfaceId) =>
+      (state.firstInterfaceId = firstInterfaceId),
     setGlobalNetworkSettings: (state, data) => {
       state.globalNetworkSettings = data.map(({ data }) => {
         const {
+          DHCPv4,
           HostName,
-          LinkStatus,
-          IPv4StaticAddresses,
           IPv4Addresses,
+          IPv4StaticAddresses,
+          LinkStatus,
         } = data;
         return {
-          hostname: HostName,
-          linkStatus: LinkStatus,
-          staticAddress: IPv4StaticAddresses[0]?.Address,
           dhcpAddress: IPv4Addresses.filter(
             (ipv4) => ipv4.AddressOrigin === 'DHCP'
           ),
+          hostname: HostName,
+          linkStatus: LinkStatus,
+          staticAddress: IPv4StaticAddresses[0]?.Address, // Display first static address on overview page
+          useDnsEnabled: DHCPv4.UseDNSServers,
+          useDomainNameEnabled: DHCPv4.UseDomainName,
+          useNtpEnabled: DHCPv4.UseNTPServers,
         };
       });
     },
@@ -62,70 +61,101 @@
           const ethernetData = ethernetInterfaces.map(
             (ethernetInterface) => ethernetInterface.data
           );
-          const interfaceOptions = ethernetInterfaces.map(
-            (ethernetName) => ethernetName.data.Id
-          );
-          const addresses = ethernetData[0].IPv4StaticAddresses;
+          const firstInterfaceId = ethernetData[0].Id;
 
-          // Default gateway manually set to first gateway saved on the first interface. Default gateway property is WIP on backend
-          const defaultGateway = addresses.map((ipv4) => {
-            return ipv4.Gateway;
-          });
-
-          commit('setGlobalNetworkSettings', ethernetInterfaces);
-          commit('setDefaultGateway', defaultGateway[0]);
           commit('setEthernetData', ethernetData);
-          commit('setInterfaceOptions', interfaceOptions);
+          commit('setFirstInterfaceId', firstInterfaceId);
+          commit('setGlobalNetworkSettings', ethernetInterfaces);
         })
         .catch((error) => {
           console.log('Network Data:', error);
         });
     },
-
-    async updateInterfaceSettings({ dispatch, state }, networkSettingsForm) {
-      const updatedAddresses = networkSettingsForm.staticIpv4;
-      const originalAddresses =
-        state.ethernetData[networkSettingsForm.selectedInterfaceIndex]
-          .IPv4StaticAddresses;
-
-      const addressArray = originalAddresses.map((item) => {
-        const address = item.Address;
-        if (find(updatedAddresses, { Address: address })) {
-          remove(updatedAddresses, (item) => {
-            return item.Address === address;
-          });
-          return {};
-        } else {
-          return null;
-        }
-      });
-
+    async saveDomainNameState({ commit, state }, domainState) {
+      commit('setDomainNameState', domainState);
       const data = {
-        HostName: networkSettingsForm.hostname,
-        MACAddress: networkSettingsForm.macAddress,
         DHCPv4: {
-          DHCPEnabled: networkSettingsForm.isDhcpEnabled,
+          UseDomainName: domainState,
         },
       };
-
-      // If DHCP disabled, update static DNS or static ipv4
-      if (!networkSettingsForm.isDhcpEnabled) {
-        data.IPv4StaticAddresses = [...addressArray, ...updatedAddresses];
-        data.StaticNameServers = networkSettingsForm.staticNameServers;
-      }
-
-      return await api
+      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
+      // on all interfaces
+      return api
         .patch(
-          `/redfish/v1/Managers/bmc/EthernetInterfaces/${networkSettingsForm.interfaceId}`,
+          `/redfish/v1/Managers/bmc/EthernetInterfaces/${state.firstInterfaceId}`,
           data
         )
-        .then(() => dispatch('getEthernetData'))
         .then(() => {
-          return i18n.t('pageNetwork.toast.successSaveNetworkSettings');
+          return i18n.t('pageNetwork.toast.successSaveNetworkSettings', {
+            setting: i18n.t('pageNetwork.domainName'),
+          });
         })
         .catch((error) => {
           console.log(error);
-          throw new Error(i18n.t('pageNetwork.toast.errorSaveNetworkSettings'));
+          commit('setDomainNameState', !domainState);
+          throw new Error(
+            i18n.t('pageNetwork.toast.errorSaveNetworkSettings', {
+              setting: i18n.t('pageNetwork.domainName'),
+            })
+          );
+        });
+    },
+    async saveDnsState({ commit, state }, dnsState) {
+      commit('setDnsState', dnsState);
+      const data = {
+        DHCPv4: {
+          UseDNSServers: dnsState,
+        },
+      };
+      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
+      // on all interfaces
+      return api
+        .patch(
+          `/redfish/v1/Managers/bmc/EthernetInterfaces/${state.firstInterfaceId}`,
+          data
+        )
+        .then(() => {
+          return i18n.t('pageNetwork.toast.successSaveNetworkSettings', {
+            setting: i18n.t('pageNetwork.dns'),
+          });
+        })
+        .catch((error) => {
+          console.log(error);
+          commit('setDnsState', !dnsState);
+          throw new Error(
+            i18n.t('pageNetwork.toast.errorSaveNetworkSettings', {
+              setting: i18n.t('pageNetwork.dns'),
+            })
+          );
+        });
+    },
+    async saveNtpState({ commit, state }, ntpState) {
+      commit('setNtpState', ntpState);
+      const data = {
+        DHCPv4: {
+          UseDNSServers: ntpState,
+        },
+      };
+      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
+      // on all interfaces
+      return api
+        .patch(
+          `/redfish/v1/Managers/bmc/EthernetInterfaces/${state.firstInterfaceId}`,
+          data
+        )
+        .then(() => {
+          return i18n.t('pageNetwork.toast.successSaveNetworkSettings', {
+            setting: i18n.t('pageNetwork.ntp'),
+          });
+        })
+        .catch((error) => {
+          console.log(error);
+          commit('setNtpState', !ntpState);
+          throw new Error(
+            i18n.t('pageNetwork.toast.errorSaveNetworkSettings', {
+              setting: i18n.t('pageNetwork.ntp'),
+            })
+          );
         });
     },
   },
diff --git a/src/views/Settings/Network/Network.vue b/src/views/Settings/Network/Network.vue
index ab5003f..918c8e9 100644
--- a/src/views/Settings/Network/Network.vue
+++ b/src/views/Settings/Network/Network.vue
@@ -1,663 +1,102 @@
 <template>
   <b-container fluid="xl">
     <page-title :description="$t('pageNetwork.pageDescription')" />
-    <page-section :section-title="$t('pageNetwork.interface')">
+    <!-- Global settings for all interfaces -->
+    <network-global-settings />
+    <!-- Interface tabs -->
+    <page-section>
       <b-row>
-        <b-col lg="3">
-          <b-form-group
-            label-for="interface-select"
-            :label="$t('pageNetwork.form.networkInterface')"
-          >
-            <b-form-select
-              id="interface-select"
-              v-model="selectedInterfaceIndex"
-              :disabled="loading"
-              data-test-id="network-select-interface"
-              :options="interfaceSelectOptions"
-              @change="selectInterface"
+        <b-col>
+          <b-card no-body>
+            <b-tabs
+              active-nav-item-class="font-weight-bold"
+              card
+              content-class="mt-3"
             >
-            </b-form-select>
-          </b-form-group>
+              <b-tab
+                v-for="(data, index) in ethernetData"
+                :key="data.Id"
+                :title="data.Id"
+                @click="getTabIndex(index)"
+              >
+                <!-- Interface settings -->
+                <network-interface-settings :tab-index="tabIndex" />
+                <!-- IPV4 table -->
+                <table-ipv-4 :tab-index="tabIndex" />
+                <!-- Static DNS table -->
+                <table-dns :tab-index="tabIndex" />
+              </b-tab>
+            </b-tabs>
+          </b-card>
         </b-col>
       </b-row>
     </page-section>
-    <b-form novalidate @submit.prevent="submitForm">
-      <b-form-group :disabled="loading">
-        <page-section :section-title="$t('pageNetwork.system')">
-          <b-row>
-            <b-col lg="3">
-              <b-form-group
-                :label="$t('pageNetwork.form.defaultGateway')"
-                label-for="default-gateway"
-              >
-                <b-form-input
-                  id="default-gateway"
-                  v-model.trim="form.gateway"
-                  data-test-id="network-input-gateway"
-                  type="text"
-                  :state="getValidationState($v.form.gateway)"
-                  @change="$v.form.gateway.$touch()"
-                />
-                <b-form-invalid-feedback role="alert">
-                  <div v-if="!$v.form.gateway.required">
-                    {{ $t('global.form.fieldRequired') }}
-                  </div>
-                  <div v-if="!$v.form.gateway.ipAddress">
-                    {{ $t('global.form.invalidFormat') }}
-                  </div>
-                </b-form-invalid-feedback>
-              </b-form-group>
-            </b-col>
-            <b-col lg="3">
-              <b-form-group
-                :label="$t('pageNetwork.form.hostname')"
-                label-for="hostname-field"
-              >
-                <b-form-input
-                  id="hostname-field"
-                  v-model.trim="form.hostname"
-                  data-test-id="network-input-hostname"
-                  type="text"
-                  :state="getValidationState($v.form.hostname)"
-                  @change="$v.form.hostname.$touch()"
-                />
-                <b-form-invalid-feedback role="alert">
-                  <div v-if="!$v.form.hostname.required">
-                    {{ $t('global.form.fieldRequired') }}
-                  </div>
-                  <div v-if="!$v.form.hostname.validateHostname">
-                    {{
-                      $t('global.form.lengthMustBeBetween', { min: 1, max: 64 })
-                    }}
-                  </div>
-                </b-form-invalid-feedback>
-              </b-form-group>
-            </b-col>
-            <b-col lg="3">
-              <b-form-group
-                :label="$t('pageNetwork.form.macAddress')"
-                label-for="mac-address"
-              >
-                <b-form-input
-                  id="mac-address"
-                  v-model.trim="form.macAddress"
-                  data-test-id="network-input-macAddress"
-                  type="text"
-                  :state="getValidationState($v.form.macAddress)"
-                  @change="$v.form.macAddress.$touch()"
-                />
-                <b-form-invalid-feedback role="alert">
-                  <div v-if="!$v.form.macAddress.required">
-                    {{ $t('global.form.fieldRequired') }}
-                  </div>
-                  <div v-if="!$v.form.macAddress.macAddress">
-                    {{ $t('global.form.invalidFormat') }}
-                  </div>
-                </b-form-invalid-feedback>
-              </b-form-group>
-            </b-col>
-          </b-row>
-        </page-section>
-        <page-section :section-title="$t('pageNetwork.ipv4')">
-          <b-form-group :label="$t('pageNetwork.ipv4Configuration')">
-            <b-form-text id="enable-secure-help-block">
-              {{ $t('pageNetwork.ipv4Helper') }}
-            </b-form-text>
-            <b-form-radio
-              v-model="form.dhcpEnabled"
-              name="dhcp-radio"
-              :value="true"
-              @change="onChangeIpv4Config"
-            >
-              {{ $t('pageNetwork.dhcp') }}
-            </b-form-radio>
-            <b-form-radio
-              v-model="form.dhcpEnabled"
-              name="static-radio"
-              :value="false"
-              @change="onChangeIpv4Config"
-            >
-              {{ $t('pageNetwork.static') }}
-            </b-form-radio>
-          </b-form-group>
-          <b-row>
-            <b-col lg="9" class="mb-3">
-              <h3 class="h4">
-                {{ $t('pageNetwork.dhcp') }}
-              </h3>
-              <b-table
-                responsive="md"
-                hover
-                :fields="ipv4DhcpTableFields"
-                :items="form.ipv4DhcpTableItems"
-                :empty-text="$t('global.table.emptyMessage')"
-                class="mb-0"
-                show-empty
-              >
-                <template #cell(Address)="{ item, index }">
-                  <b-form-input
-                    v-model.trim="item.Address"
-                    :data-test-id="`network-input-dhcpIpv4-${index}`"
-                    :aria-label="
-                      $t('pageNetwork.table.dhcpIpv4AddressRow') +
-                      ' ' +
-                      (index + 1)
-                    "
-                    readonly
-                  />
-                </template>
-                <template #cell(SubnetMask)="{ item, index }">
-                  <b-form-input
-                    v-model.trim="item.SubnetMask"
-                    :data-test-id="`network-input-subnetMask-${index}`"
-                    :aria-label="
-                      $t('pageNetwork.table.dhcpIpv4SubnetRow') +
-                      ' ' +
-                      (index + 1)
-                    "
-                    readonly
-                  />
-                </template>
-                <template #cell(actions)="{ item, index }">
-                  <table-row-action
-                    v-for="(action, actionIndex) in item.actions"
-                    :key="actionIndex"
-                    :value="action.value"
-                    :title="action.title"
-                    :enabled="false"
-                    @click-table-action="
-                      onDeleteIpv4StaticTableRow($event, index)
-                    "
-                  >
-                    <template #icon>
-                      <icon-trashcan v-if="action.value === 'delete'" />
-                    </template>
-                  </table-row-action>
-                </template>
-              </b-table>
-            </b-col>
-            <b-col lg="9" class="mb-3">
-              <h3 class="h4">
-                {{ $t('pageNetwork.static') }}
-              </h3>
-              <b-table
-                responsive="md"
-                hover
-                :fields="ipv4StaticTableFields"
-                :items="form.ipv4StaticTableItems"
-                :empty-text="$t('global.table.emptyMessage')"
-                class="mb-0"
-                show-empty
-              >
-                <template #cell(Address)="{ item, index }">
-                  <b-form-input
-                    v-model.trim="item.Address"
-                    :data-test-id="`network-input-staticIpv4-${index}`"
-                    :aria-label="
-                      $t('pageNetwork.table.staticIpv4AddressRow') +
-                      ' ' +
-                      (index + 1)
-                    "
-                    :state="
-                      getValidationState(
-                        $v.form.ipv4StaticTableItems.$each.$iter[index].Address
-                      )
-                    "
-                    @change="
-                      $v.form.ipv4StaticTableItems.$each.$iter[
-                        index
-                      ].Address.$touch()
-                    "
-                  />
-                  <b-form-invalid-feedback role="alert">
-                    <div
-                      v-if="
-                        !$v.form.ipv4StaticTableItems.$each.$iter[index].Address
-                          .required
-                      "
-                    >
-                      {{ $t('global.form.fieldRequired') }}
-                    </div>
-                    <div
-                      v-if="
-                        !$v.form.ipv4StaticTableItems.$each.$iter[index].Address
-                          .ipAddress
-                      "
-                    >
-                      {{ $t('global.form.invalidFormat') }}
-                    </div>
-                  </b-form-invalid-feedback>
-                </template>
-                <template #cell(SubnetMask)="{ item, index }">
-                  <b-form-input
-                    v-model.trim="item.SubnetMask"
-                    :data-test-id="`network-input-subnetMask-${index}`"
-                    :aria-label="
-                      $t('pageNetwork.table.staticIpv4SubnetRow') +
-                      ' ' +
-                      (index + 1)
-                    "
-                    :state="
-                      getValidationState(
-                        $v.form.ipv4StaticTableItems.$each.$iter[index]
-                          .SubnetMask
-                      )
-                    "
-                    @change="
-                      $v.form.ipv4StaticTableItems.$each.$iter[
-                        index
-                      ].SubnetMask.$touch()
-                    "
-                  />
-                  <b-form-invalid-feedback role="alert">
-                    <div
-                      v-if="
-                        !$v.form.ipv4StaticTableItems.$each.$iter[index]
-                          .SubnetMask.required
-                      "
-                    >
-                      {{ $t('global.form.fieldRequired') }}
-                    </div>
-                    <div
-                      v-if="
-                        !$v.form.ipv4StaticTableItems.$each.$iter[index]
-                          .SubnetMask.ipAddress
-                      "
-                    >
-                      {{ $t('global.form.invalidFormat') }}
-                    </div>
-                  </b-form-invalid-feedback>
-                </template>
-                <template #cell(actions)="{ item, index }">
-                  <table-row-action
-                    v-for="(action, actionIndex) in item.actions"
-                    :key="actionIndex"
-                    :value="action.value"
-                    :title="action.title"
-                    @click-table-action="
-                      onDeleteIpv4StaticTableRow($event, index)
-                    "
-                  >
-                    <template #icon>
-                      <icon-trashcan v-if="action.value === 'delete'" />
-                    </template>
-                  </table-row-action>
-                </template>
-              </b-table>
-              <b-button variant="link" @click="addIpv4StaticTableRow">
-                <icon-add />
-                {{ $t('pageNetwork.table.addStaticIpv4Address') }}
-              </b-button>
-            </b-col>
-          </b-row>
-        </page-section>
-        <page-section :section-title="$t('pageNetwork.staticDns')">
-          <b-row>
-            <b-col lg="4" class="mb-3">
-              <b-table
-                responsive
-                hover
-                :fields="dnsTableFields"
-                :items="form.dnsStaticTableItems"
-                :empty-text="$t('global.table.emptyMessage')"
-                class="mb-0"
-                show-empty
-              >
-                <template #cell(address)="{ item, index }">
-                  <b-form-input
-                    v-model.trim="item.address"
-                    :data-test-id="`network-input-dnsAddress-${index}`"
-                    :aria-label="
-                      $t('pageNetwork.table.staticDnsRow') + ' ' + (index + 1)
-                    "
-                    :state="
-                      getValidationState(
-                        $v.form.dnsStaticTableItems.$each.$iter[index].address
-                      )
-                    "
-                    @change="
-                      $v.form.dnsStaticTableItems.$each.$iter[
-                        index
-                      ].address.$touch()
-                    "
-                  />
-                  <b-form-invalid-feedback role="alert">
-                    <div
-                      v-if="
-                        !$v.form.dnsStaticTableItems.$each.$iter[index].address
-                          .required
-                      "
-                    >
-                      {{ $t('global.form.fieldRequired') }}
-                    </div>
-                    <div
-                      v-if="
-                        !$v.form.dnsStaticTableItems.$each.$iter[index].address
-                          .ipAddress
-                      "
-                    >
-                      {{ $t('global.form.invalidFormat') }}
-                    </div>
-                  </b-form-invalid-feedback>
-                </template>
-                <template #cell(actions)="{ item, index }">
-                  <table-row-action
-                    v-for="(action, actionIndex) in item.actions"
-                    :key="actionIndex"
-                    :value="action.value"
-                    :title="action.title"
-                    @click-table-action="onDeleteDnsTableRow($event, index)"
-                  >
-                    <template #icon>
-                      <icon-trashcan v-if="action.value === 'delete'" />
-                    </template>
-                  </table-row-action>
-                </template>
-              </b-table>
-              <b-button variant="link" @click="addDnsTableRow">
-                <icon-add /> {{ $t('pageNetwork.table.addDns') }}
-              </b-button>
-            </b-col>
-          </b-row>
-        </page-section>
-        <b-button
-          variant="primary"
-          type="submit"
-          data-test-id="network-button-saveNetworkSettings"
-        >
-          {{ $t('global.action.saveSettings') }}
-        </b-button>
-      </b-form-group>
-    </b-form>
   </b-container>
 </template>
 
 <script>
-import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
-import IconAdd from '@carbon/icons-vue/es/add--alt/20';
 import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
 import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import NetworkGlobalSettings from './NetworkGlobalSettings.vue';
+import NetworkInterfaceSettings from './NetworkInterfaceSettings.vue';
 import PageSection from '@/components/Global/PageSection';
 import PageTitle from '@/components/Global/PageTitle';
-import TableRowAction from '@/components/Global/TableRowAction';
-import VuelidateMixin from '@/components/Mixins/VuelidateMixin';
+import TableIpv4 from './TableIpv4.vue';
+import TableDns from './TableDns.vue';
 import { mapState } from 'vuex';
-import {
-  required,
-  helpers,
-  ipAddress,
-  macAddress,
-} from 'vuelidate/lib/validators';
-
-// Hostname pattern
-const validateHostname = helpers.regex('validateHostname', /^\S{0,64}$/);
 
 export default {
   name: 'Network',
   components: {
-    PageTitle,
+    NetworkGlobalSettings,
+    NetworkInterfaceSettings,
     PageSection,
-    TableRowAction,
-    IconTrashcan,
-    IconAdd,
+    PageTitle,
+    TableDns,
+    TableIpv4,
   },
-  mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin],
+  mixins: [BVToastMixin, DataFormatterMixin, LoadingBarMixin],
   beforeRouteLeave(to, from, next) {
     this.hideLoader();
     next();
   },
   data() {
     return {
-      ipv4DhcpTableFields: [
-        {
-          key: 'Address',
-          label: this.$t('pageNetwork.table.ipAddress'),
-        },
-        {
-          key: 'SubnetMask',
-          label: this.$t('pageNetwork.table.subnet'),
-        },
-        { key: 'actions', label: '', tdClass: 'text-right' },
-      ],
-      ipv4StaticTableFields: [
-        {
-          key: 'Address',
-          label: this.$t('pageNetwork.table.ipAddress'),
-        },
-        {
-          key: 'SubnetMask',
-          label: this.$t('pageNetwork.table.subnet'),
-        },
-        { key: 'actions', label: '', tdClass: 'text-right' },
-      ],
-      dnsTableFields: [
-        {
-          key: 'address',
-          label: this.$t('pageNetwork.table.ipAddress'),
-        },
-        { key: 'actions', label: '', tdClass: 'text-right' },
-      ],
-      selectedInterfaceIndex: 0,
-      selectedInterface: {},
-      form: {
-        dhcpEnabled: null,
-        gateway: '',
-        hostname: '',
-        macAddress: '',
-        ipv4StaticTableItems: [],
-        ipv4DhcpTableItems: [],
-        dnsStaticTableItems: [],
-      },
       loading,
-    };
-  },
-  validations() {
-    return {
-      form: {
-        gateway: { required, ipAddress },
-        hostname: { required, validateHostname },
-        ipv4StaticTableItems: {
-          $each: {
-            Address: {
-              required,
-              ipAddress,
-            },
-            SubnetMask: {
-              required,
-              ipAddress,
-            },
-          },
-        },
-        macAddress: { required, macAddress: macAddress() },
-        dnsStaticTableItems: {
-          $each: {
-            address: {
-              required,
-              ipAddress,
-            },
-          },
-        },
-      },
+      tabIndex: 0,
     };
   },
   computed: {
-    ...mapState('network', [
-      'ethernetData',
-      'interfaceOptions',
-      'defaultGateway',
-    ]),
-    interfaceSelectOptions() {
-      return this.interfaceOptions.map((option, index) => {
-        return {
-          text: option,
-          value: index,
-        };
-      });
-    },
-  },
-  watch: {
-    ethernetData: function () {
-      this.selectInterface();
-    },
+    ...mapState('network', ['ethernetData']),
   },
   created() {
     this.startLoader();
-    this.$store
-      .dispatch('network/getEthernetData')
-      .finally(() => this.endLoader());
+    const globalSettings = new Promise((resolve) => {
+      this.$root.$on('network-global-settings-complete', () => resolve());
+    });
+    const interfaceSettings = new Promise((resolve) => {
+      this.$root.$on('network-interface-settings-complete', () => resolve());
+    });
+    const networkTableDns = new Promise((resolve) => {
+      this.$root.$on('network-table-dns-complete', () => resolve());
+    });
+    const networkTableIpv4 = new Promise((resolve) => {
+      this.$root.$on('network-table-ipv4-complete', () => resolve());
+    });
+    // Combine all child component Promises to indicate
+    // when page data load complete
+    Promise.all([
+      this.$store.dispatch('network/getEthernetData'),
+      globalSettings,
+      interfaceSettings,
+      networkTableDns,
+      networkTableIpv4,
+    ]).finally(() => this.endLoader());
   },
   methods: {
-    selectInterface() {
-      this.selectedInterface = this.ethernetData[this.selectedInterfaceIndex];
-      this.getIpv4DhcpTableItems();
-      this.getIpv4StaticTableItems();
-      this.getDnsStaticTableItems();
-      this.getInterfaceSettings();
-    },
-    getInterfaceSettings() {
-      this.form.gateway = this.defaultGateway;
-      this.form.hostname = this.selectedInterface.HostName;
-      this.form.macAddress = this.selectedInterface.MACAddress;
-      this.form.dhcpEnabled = this.selectedInterface.DHCPv4.DHCPEnabled;
-    },
-    onChangeIpv4Config(value) {
-      this.form.dhcpEnabled = value;
-    },
-    getDnsStaticTableItems() {
-      const dns = this.selectedInterface.StaticNameServers || [];
-      this.form.dnsStaticTableItems = dns.map((server) => {
-        return {
-          address: server,
-          actions: [
-            {
-              value: 'delete',
-              enabled: this.form.dhcpEnabled,
-              title: this.$t('pageNetwork.table.deleteDns'),
-            },
-          ],
-        };
-      });
-    },
-    addDnsTableRow() {
-      this.$v.form.dnsStaticTableItems.$touch();
-      this.form.dnsStaticTableItems.push({
-        address: '',
-        actions: [
-          {
-            value: 'delete',
-            enabled: this.form.dhcpEnabled,
-            title: this.$t('pageNetwork.table.deleteDns'),
-          },
-        ],
-      });
-    },
-    deleteDnsTableRow(index) {
-      this.$v.form.dnsStaticTableItems.$touch();
-      this.form.dnsStaticTableItems.splice(index, 1);
-    },
-    onDeleteDnsTableRow(action, row) {
-      this.deleteDnsTableRow(row);
-    },
-    getIpv4DhcpTableItems() {
-      const addresses = this.selectedInterface.IPv4Addresses || [];
-      this.form.ipv4DhcpTableItems = addresses
-        .filter((ipv4) => ipv4.AddressOrigin === 'DHCP')
-        .map((ipv4) => {
-          return {
-            Address: ipv4.Address,
-            SubnetMask: ipv4.SubnetMask,
-            actions: [
-              {
-                value: 'delete',
-                enabled: false,
-                title: this.$t('pageNetwork.table.deleteDhcpIpv4'),
-              },
-            ],
-          };
-        });
-    },
-    getIpv4StaticTableItems() {
-      const addresses = this.selectedInterface.IPv4StaticAddresses || [];
-      this.form.ipv4StaticTableItems = addresses.map((ipv4) => {
-        return {
-          Address: ipv4.Address,
-          SubnetMask: ipv4.SubnetMask,
-          actions: [
-            {
-              value: 'delete',
-              enabled: this.form.dhcpEnabled,
-              title: this.$t('pageNetwork.table.deleteStaticIpv4'),
-            },
-          ],
-        };
-      });
-    },
-    addIpv4StaticTableRow() {
-      this.$v.form.ipv4StaticTableItems.$touch();
-      this.form.ipv4StaticTableItems.push({
-        Address: '',
-        SubnetMask: '',
-        actions: [
-          {
-            value: 'delete',
-            enabled: this.form.dhcpEnabled,
-            title: this.$t('pageNetwork.table.deleteStaticIpv4'),
-          },
-        ],
-      });
-    },
-    deleteIpv4StaticTableRow(index) {
-      this.$v.form.ipv4StaticTableItems.$touch();
-      this.form.ipv4StaticTableItems.splice(index, 1);
-    },
-    onDeleteIpv4StaticTableRow(action, row) {
-      this.deleteIpv4StaticTableRow(row);
-    },
-    submitForm() {
-      this.$v.$touch();
-      if (this.$v.$invalid) return;
-      this.startLoader();
-      let networkInterfaceSelected = this.selectedInterface;
-      let selectedInterfaceIndex = this.selectedInterfaceIndex;
-      let interfaceId = networkInterfaceSelected.Id;
-      let isDhcpEnabled = this.form.dhcpEnabled;
-      let macAddress = this.form.macAddress;
-      let hostname = this.form.hostname;
-      let networkSettingsForm = {
-        interfaceId,
-        hostname,
-        macAddress,
-        selectedInterfaceIndex,
-      };
-      // Enabling DHCP without any available IP addresses will bring network down
-      if (this.form.ipv4DhcpTableItems.length) {
-        networkSettingsForm.isDhcpEnabled = isDhcpEnabled;
-      } else {
-        networkSettingsForm.isDhcpEnabled = false;
-        this.errorToast(this.$t('pageNetwork.toast.errorSaveDhcpSettings'));
-      }
-      networkSettingsForm.staticIpv4 = this.form.ipv4StaticTableItems.map(
-        (updateIpv4) => {
-          delete updateIpv4.actions;
-          updateIpv4.Gateway = this.form.gateway;
-          return updateIpv4;
-        }
-      );
-      networkSettingsForm.staticNameServers = this.form.dnsStaticTableItems.map(
-        (updateDns) => {
-          return updateDns.address;
-        }
-      );
-      this.$store
-        .dispatch('network/updateInterfaceSettings', networkSettingsForm)
-        .then((success) => {
-          this.successToast(success);
-        })
-        .catch(({ message }) => this.errorToast(message))
-        .finally(() => {
-          this.$v.form.$reset();
-          this.endLoader();
-        });
+    getTabIndex(selectedIndex) {
+      this.tabIndex = selectedIndex;
     },
   },
 };
diff --git a/src/views/Settings/Network/NetworkGlobalSettings.vue b/src/views/Settings/Network/NetworkGlobalSettings.vue
new file mode 100644
index 0000000..fc82c86
--- /dev/null
+++ b/src/views/Settings/Network/NetworkGlobalSettings.vue
@@ -0,0 +1,152 @@
+<template>
+  <page-section
+    v-if="firstInterface"
+    :section-title="$t('pageNetwork.networkSettings')"
+  >
+    <b-row>
+      <b-col md="3">
+        <dl>
+          <dt>{{ $t('pageNetwork.hostname') }}</dt>
+          <dd>{{ dataFormatter(firstInterface.hostname) }}</dd>
+        </dl>
+      </b-col>
+      <b-col md="3">
+        <dl>
+          <dt>{{ $t('pageNetwork.useDomainName') }}</dt>
+          <dd>
+            <b-form-checkbox
+              id="useDomainNameSwitch"
+              v-model="useDomainNameState"
+              data-test-id="networkSettings-switch-useDomainName"
+              switch
+              @change="changeDomainNameState"
+            >
+              <span v-if="useDomainNameState">
+                {{ $t('global.status.enabled') }}
+              </span>
+              <span v-else>{{ $t('global.status.disabled') }}</span>
+            </b-form-checkbox>
+          </dd>
+        </dl>
+      </b-col>
+      <b-col md="3">
+        <dl>
+          <dt>{{ $t('pageNetwork.useDns') }}</dt>
+          <dd>
+            <b-form-checkbox
+              id="useDnsSwitch"
+              v-model="useDnsState"
+              data-test-id="networkSettings-switch-useDns"
+              switch
+              @change="changeDnsState"
+            >
+              <span v-if="useDnsState">
+                {{ $t('global.status.enabled') }}
+              </span>
+              <span v-else>{{ $t('global.status.disabled') }}</span>
+            </b-form-checkbox>
+          </dd>
+        </dl>
+      </b-col>
+      <b-col md="3">
+        <dl>
+          <dt>{{ $t('pageNetwork.useNtp') }}</dt>
+          <dd>
+            <b-form-checkbox
+              id="useNtpSwitch"
+              v-model="useNtpState"
+              data-test-id="networkSettings-switch-useNtp"
+              switch
+              @change="changeNtpState"
+            >
+              <span v-if="useNtpState">
+                {{ $t('global.status.enabled') }}
+              </span>
+              <span v-else>{{ $t('global.status.disabled') }}</span>
+            </b-form-checkbox>
+          </dd>
+        </dl>
+      </b-col>
+    </b-row>
+  </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import PageSection from '@/components/Global/PageSection';
+import { mapState } from 'vuex';
+
+export default {
+  name: 'GlobalNetworkSettings',
+  components: { PageSection },
+  mixins: [BVToastMixin, DataFormatterMixin],
+
+  data() {
+    return {
+      hostname: '',
+    };
+  },
+  computed: {
+    ...mapState('network', ['ethernetData']),
+    firstInterface() {
+      return this.$store.getters['network/globalNetworkSettings'][0];
+    },
+    useDomainNameState: {
+      get() {
+        return this.$store.getters['network/globalNetworkSettings'][0]
+          .useDomainNameEnabled;
+      },
+      set(newValue) {
+        return newValue;
+      },
+    },
+    useDnsState: {
+      get() {
+        return this.$store.getters['network/globalNetworkSettings'][0]
+          .useDnsEnabled;
+      },
+      set(newValue) {
+        return newValue;
+      },
+    },
+    useNtpState: {
+      get() {
+        return this.$store.getters['network/globalNetworkSettings'][0]
+          .useNtpEnabled;
+      },
+      set(newValue) {
+        return newValue;
+      },
+    },
+  },
+  created() {
+    this.$store.dispatch('network/getEthernetData').finally(() => {
+      // Emit initial data fetch complete to parent component
+      this.$root.$emit('network-global-settings-complete');
+    });
+  },
+  methods: {
+    changeDomainNameState(state) {
+      this.$store
+        .dispatch('network/saveDomainNameState', state)
+        .then((success) => {
+          this.successToast(success);
+        })
+        .catch(({ message }) => this.errorToast(message));
+    },
+    changeDnsState(state) {
+      this.$store
+        .dispatch('network/saveDnsState', state)
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message));
+    },
+    changeNtpState(state) {
+      this.$store
+        .dispatch('network/saveNtpState', state)
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message));
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/Network/NetworkInterfaceSettings.vue b/src/views/Settings/Network/NetworkInterfaceSettings.vue
new file mode 100644
index 0000000..bdcba4d
--- /dev/null
+++ b/src/views/Settings/Network/NetworkInterfaceSettings.vue
@@ -0,0 +1,99 @@
+<template>
+  <div>
+    <page-section>
+      <b-row>
+        <b-col md="3">
+          <dl>
+            <dt>{{ $t('pageNetwork.linkStatus') }}</dt>
+            <dd>
+              {{ dataFormatter(linkStatus) }}
+            </dd>
+          </dl>
+        </b-col>
+        <b-col md="3">
+          <dl>
+            <dt>{{ $t('pageNetwork.speed') }}</dt>
+            <dd>
+              {{ dataFormatter(linkSpeed) }}
+            </dd>
+          </dl>
+        </b-col>
+      </b-row>
+    </page-section>
+    <page-section :section-title="$t('pageNetwork.interfaceSection')">
+      <b-row>
+        <b-col md="3">
+          <dl>
+            <dt>{{ $t('pageNetwork.fqdn') }}</dt>
+            <dd>
+              {{ dataFormatter(fqdn) }}
+            </dd>
+          </dl>
+        </b-col>
+        <b-col md="3">
+          <dl class="text-nowrap">
+            <dt>{{ $t('pageNetwork.macAddress') }}</dt>
+            <dd>
+              {{ dataFormatter(macAddress) }}
+            </dd>
+          </dl>
+        </b-col>
+      </b-row>
+    </page-section>
+  </div>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import { mapState } from 'vuex';
+
+export default {
+  name: 'Ipv4Table',
+  components: {
+    PageSection,
+  },
+  mixins: [BVToastMixin, DataFormatterMixin],
+  props: {
+    tabIndex: {
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      selectedInterface: '',
+      linkStatus: '',
+      linkSpeed: '',
+      fqdn: '',
+      macAddress: '',
+    };
+  },
+  computed: {
+    ...mapState('network', ['ethernetData']),
+  },
+  watch: {
+    // Watch for change in tab index
+    tabIndex() {
+      this.getSettings();
+    },
+  },
+  created() {
+    this.getSettings();
+    this.$store.dispatch('network/getEthernetData').finally(() => {
+      // Emit initial data fetch complete to parent component
+      this.$root.$emit('network-interface-settings-complete');
+    });
+  },
+  methods: {
+    getSettings() {
+      this.selectedInterface = this.tabIndex;
+      this.linkStatus = this.ethernetData[this.selectedInterface].LinkStatus;
+      this.linkSpeed = this.ethernetData[this.selectedInterface].SpeedMbps;
+      this.fqdn = this.ethernetData[this.selectedInterface].FQDN;
+      this.macAddress = this.ethernetData[this.selectedInterface].MACAddress;
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/Network/TableDns.vue b/src/views/Settings/Network/TableDns.vue
new file mode 100644
index 0000000..2578ba3
--- /dev/null
+++ b/src/views/Settings/Network/TableDns.vue
@@ -0,0 +1,126 @@
+<template>
+  <page-section :section-title="$t('pageNetwork.staticDns')">
+    <b-row>
+      <b-col lg="6">
+        <b-table
+          responsive="md"
+          hover
+          :fields="dnsTableFields"
+          :items="form.dnsStaticTableItems"
+          :empty-text="$t('global.table.emptyMessage')"
+          class="mb-0"
+          show-empty
+        >
+          <template #cell(actions)="{ item }">
+            <table-row-action
+              v-for="(action, actionIndex) in item.actions"
+              :key="actionIndex"
+              :value="action.value"
+              :title="action.title"
+              :enabled="action.enabled"
+              @click-table-action="onDnsTableAction(action, $event, index)"
+            >
+              <template #icon>
+                <icon-edit v-if="action.value === 'edit'" />
+                <icon-trashcan v-if="action.value === 'delete'" />
+              </template>
+            </table-row-action>
+          </template>
+        </b-table>
+      </b-col>
+    </b-row>
+  </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconEdit from '@carbon/icons-vue/es/edit/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import PageSection from '@/components/Global/PageSection';
+import TableRowAction from '@/components/Global/TableRowAction';
+import { mapState } from 'vuex';
+
+export default {
+  name: 'DNSTable',
+  components: {
+    IconEdit,
+    IconTrashcan,
+    PageSection,
+    TableRowAction,
+  },
+  mixins: [BVToastMixin],
+  props: {
+    tabIndex: {
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      form: {
+        dnsStaticTableItems: [],
+      },
+      actions: [
+        {
+          value: 'edit',
+          title: this.$t('global.action.edit'),
+        },
+        {
+          value: 'delete',
+          title: this.$t('global.action.delete'),
+        },
+      ],
+      dnsTableFields: [
+        {
+          key: 'address',
+          label: this.$t('pageNetwork.table.ipAddress'),
+        },
+        { key: 'actions', label: '', tdClass: 'text-right' },
+      ],
+    };
+  },
+  computed: {
+    ...mapState('network', ['ethernetData']),
+  },
+  watch: {
+    // Watch for change in tab index
+    tabIndex() {
+      this.getStaticDnsItems();
+    },
+  },
+  created() {
+    this.getStaticDnsItems();
+    this.$store.dispatch('network/getEthernetData').finally(() => {
+      // Emit initial data fetch complete to parent component
+      this.$root.$emit('network-table-dns-complete');
+    });
+  },
+  methods: {
+    getStaticDnsItems() {
+      const index = this.tabIndex;
+      const dns = this.ethernetData[index].StaticNameServers || [];
+      this.form.dnsStaticTableItems = dns.map((server) => {
+        return {
+          address: server,
+          actions: [
+            {
+              value: 'edit',
+              title: this.$t('pageNetwork.table.editDns'),
+            },
+            {
+              value: 'delete',
+              title: this.$t('pageNetwork.table.deleteDns'),
+            },
+          ],
+        };
+      });
+    },
+    onDnsTableAction(action, row) {
+      if (action === 'delete') {
+        this.form.dnsStaticTableItems.splice(row, 1);
+        // TODO: delete row in store
+      }
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/Network/TableIpv4.vue b/src/views/Settings/Network/TableIpv4.vue
new file mode 100644
index 0000000..5e4bb7b
--- /dev/null
+++ b/src/views/Settings/Network/TableIpv4.vue
@@ -0,0 +1,146 @@
+<template>
+  <page-section :section-title="$t('pageNetwork.ipv4')">
+    <b-row>
+      <b-col>
+        <h3 class="h5">
+          {{ $t('pageNetwork.ipv4Addresses') }}
+        </h3>
+      </b-col>
+    </b-row>
+    <b-table
+      responsive="md"
+      hover
+      :fields="ipv4TableFields"
+      :items="form.ipv4TableItems"
+      :empty-text="$t('global.table.emptyMessage')"
+      class="mb-0"
+      show-empty
+    >
+      <template #cell(actions)="{ item }">
+        <table-row-action
+          v-for="(action, actionIndex) in item.actions"
+          :key="actionIndex"
+          :value="action.value"
+          :title="action.title"
+          :enabled="action.enabled"
+          @click-table-action="onIpv4TableAction(action, $event, index)"
+        >
+          <template #icon>
+            <icon-edit v-if="action.value === 'edit'" />
+            <icon-trashcan v-if="action.value === 'delete'" />
+          </template>
+        </table-row-action>
+      </template>
+    </b-table>
+  </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconEdit from '@carbon/icons-vue/es/edit/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import PageSection from '@/components/Global/PageSection';
+import TableRowAction from '@/components/Global/TableRowAction';
+import { mapState } from 'vuex';
+
+export default {
+  name: 'Ipv4Table',
+  components: {
+    IconEdit,
+    IconTrashcan,
+    PageSection,
+    TableRowAction,
+  },
+  mixins: [BVToastMixin],
+  props: {
+    tabIndex: {
+      type: Number,
+      default: 0,
+    },
+  },
+  data() {
+    return {
+      form: {
+        ipv4TableItems: [],
+      },
+      actions: [
+        {
+          value: 'edit',
+          title: this.$t('global.action.edit'),
+        },
+        {
+          value: 'delete',
+          title: this.$t('global.action.delete'),
+        },
+      ],
+      ipv4TableFields: [
+        {
+          key: 'Address',
+          label: this.$t('pageNetwork.table.ipAddress'),
+        },
+        {
+          key: 'Gateway',
+          label: this.$t('pageNetwork.table.gateway'),
+        },
+        {
+          key: 'SubnetMask',
+          label: this.$t('pageNetwork.table.subnet'),
+        },
+        {
+          key: 'AddressOrigin',
+          label: this.$t('pageNetwork.table.addressOrigin'),
+        },
+        { key: 'actions', label: '', tdClass: 'text-right' },
+      ],
+    };
+  },
+  computed: {
+    ...mapState('network', ['ethernetData']),
+  },
+  watch: {
+    // Watch for change in tab index
+    tabIndex() {
+      this.getIpv4TableItems();
+    },
+  },
+  created() {
+    this.getIpv4TableItems();
+    this.$store.dispatch('network/getEthernetData').finally(() => {
+      // Emit initial data fetch complete to parent component
+      this.$root.$emit('network-table-ipv4-complete');
+    });
+  },
+  methods: {
+    getIpv4TableItems() {
+      const index = this.tabIndex;
+      const addresses = this.ethernetData[index].IPv4Addresses || [];
+      this.form.ipv4TableItems = addresses.map((ipv4) => {
+        return {
+          Address: ipv4.Address,
+          SubnetMask: ipv4.SubnetMask,
+          Gateway: ipv4.Gateway,
+          AddressOrigin: ipv4.AddressOrigin,
+          actions: [
+            {
+              value: 'edit',
+              title: this.$t('pageNetwork.table.editIpv4'),
+              enabled: false,
+            },
+            {
+              value: 'delete',
+              title: this.$t('pageNetwork.table.deleteIpv4'),
+              enabled: false,
+            },
+          ],
+        };
+      });
+    },
+    onIpv4TableAction(action, row) {
+      if (action === 'delete') {
+        this.form.ipv4TableItems.splice(row, 1);
+        // TODO: delete row in store
+      }
+    },
+  },
+};
+</script>