1<template> 2 <b-container fluid="xl"> 3 <page-title :description="$t('pageNetwork.pageDescription')" /> 4 <!-- Global settings for all interfaces --> 5 <network-global-settings /> 6 <!-- Interface tabs --> 7 <page-section v-if="ethernetData && ethernetData.length"> 8 <b-row> 9 <b-col> 10 <b-card no-body> 11 <b-tabs 12 :key="tabsRenderKey" 13 v-model:index="tabIndex" 14 active-nav-item-class="fw-bold" 15 card 16 content-class="mt-3" 17 :lazy="false" 18 > 19 <b-tab 20 v-for="data in ethernetData" 21 :key="data.Id" 22 :title="data.Id" 23 > 24 <!-- Interface settings --> 25 <network-interface-settings :tab-index="tabIndex" /> 26 <!-- IPV4 table --> 27 <table-ipv-4 :tab-index="tabIndex" /> 28 <!-- IPV6 table --> 29 <table-ipv-6 :tab-index="tabIndex" /> 30 <!-- Static DNS table --> 31 <table-dns :tab-index="tabIndex" /> 32 </b-tab> 33 </b-tabs> 34 </b-card> 35 </b-col> 36 </b-row> 37 </page-section> 38 <!-- Modals --> 39 <modal-ipv4 :default-gateway="defaultGateway" @ok="saveIpv4Address" /> 40 <modal-ipv6 @ok="saveIpv6Address" /> 41 <modal-dns @ok="saveDnsAddress" /> 42 <modal-hostname 43 v-model="showHostnameModal" 44 :hostname="currentHostname" 45 @ok="saveSettings" 46 /> 47 <modal-mac-address 48 v-model="showMacAddressModal" 49 :mac-address="currentMacAddress" 50 @ok="saveSettings" 51 /> 52 <modal-default-gateway 53 v-model="showDefaultGatewayModal" 54 :default-gateway="ipv6DefaultGateway" 55 @ok="saveSettings" 56 /> 57 </b-container> 58</template> 59 60<script> 61import BVToastMixin from '@/components/Mixins/BVToastMixin'; 62import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; 63import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin'; 64import ModalMacAddress from './ModalMacAddress.vue'; 65import ModalDefaultGateway from './ModalDefaultGateway.vue'; 66import ModalHostname from './ModalHostname.vue'; 67import ModalIpv4 from './ModalIpv4.vue'; 68import ModalIpv6 from './ModalIpv6.vue'; 69import ModalDns from './ModalDns.vue'; 70import NetworkGlobalSettings from './NetworkGlobalSettings.vue'; 71import NetworkInterfaceSettings from './NetworkInterfaceSettings.vue'; 72import PageSection from '@/components/Global/PageSection'; 73import PageTitle from '@/components/Global/PageTitle'; 74import TableIpv4 from './TableIpv4.vue'; 75import TableIpv6 from './TableIpv6.vue'; 76import TableDns from './TableDns.vue'; 77import { mapState } from 'vuex'; 78import { useI18n } from 'vue-i18n'; 79 80export default { 81 name: 'Network', 82 components: { 83 ModalHostname, 84 ModalMacAddress, 85 ModalDefaultGateway, 86 ModalIpv4, 87 ModalIpv6, 88 ModalDns, 89 NetworkGlobalSettings, 90 NetworkInterfaceSettings, 91 PageSection, 92 PageTitle, 93 TableDns, 94 TableIpv4, 95 TableIpv6, 96 }, 97 mixins: [BVToastMixin, DataFormatterMixin, LoadingBarMixin], 98 beforeRouteLeave(to, from, next) { 99 this.hideLoader(); 100 next(); 101 }, 102 data() { 103 return { 104 $t: useI18n().t, 105 currentHostname: '', 106 currentMacAddress: '', 107 defaultGateway: '', 108 ipv6DefaultGateway: '', 109 loading, 110 tabIndex: 0, 111 tabsReady: false, 112 tabsRenderKey: 0, 113 showHostnameModal: false, 114 showDefaultGatewayModal: false, 115 showMacAddressModal: false, 116 }; 117 }, 118 computed: { 119 ...mapState('network', ['ethernetData']), 120 }, 121 watch: { 122 ethernetData() { 123 this.getModalInfo(); 124 }, 125 tabIndex(newIndex) { 126 this.$store.dispatch('network/setSelectedTabIndex', newIndex); 127 this.$store.dispatch( 128 'network/setSelectedTabId', 129 this.ethernetData?.[newIndex]?.Id, 130 ); 131 this.getModalInfo(); 132 }, 133 }, 134 created() { 135 this.startLoader(); 136 const eventBus = require('@/eventBus').default; 137 const globalSettings = new Promise((resolve) => { 138 eventBus.$once('network-global-settings-complete', resolve); 139 }); 140 const interfaceSettings = new Promise((resolve) => { 141 eventBus.$once('network-interface-settings-complete', resolve); 142 }); 143 const networkTableDns = new Promise((resolve) => { 144 eventBus.$once('network-table-dns-complete', resolve); 145 }); 146 const networkTableIpv4 = new Promise((resolve) => { 147 eventBus.$once('network-table-ipv4-complete', resolve); 148 }); 149 const networkTableIpv6 = new Promise((resolve) => { 150 eventBus.$once('network-table-ipv6-complete', resolve); 151 }); 152 // Combine all child component Promises to indicate 153 // when page data load complete 154 Promise.all([ 155 this.$store.dispatch('network/getEthernetData'), 156 globalSettings, 157 interfaceSettings, 158 networkTableDns, 159 networkTableIpv4, 160 networkTableIpv6, 161 ]) 162 .then(() => { 163 // ensure first tab is selected and expanded (index 0). Force a change 164 // cycle to trigger BTabs to render the pane content immediately. 165 const count = this.ethernetData?.length || 0; 166 if (count > 0) { 167 // set initial selection directly to index 0 168 this.tabIndex = 0; 169 this.$store.dispatch('network/setSelectedTabIndex', 0); 170 const firstId = this.ethernetData?.[0]?.Id; 171 if (firstId) 172 this.$store.dispatch('network/setSelectedTabId', firstId); 173 this.tabsRenderKey += 1; 174 } 175 }) 176 .finally(() => this.endLoader()); 177 }, 178 methods: { 179 getModalInfo() { 180 const settingsArray = 181 this.$store.getters['network/globalNetworkSettings']; 182 const settings = Array.isArray(settingsArray) 183 ? settingsArray[this.tabIndex] 184 : undefined; 185 186 if (!settings) return; 187 this.defaultGateway = settings.defaultGateway; 188 this.currentHostname = settings.hostname; 189 this.currentMacAddress = settings.macAddress; 190 this.ipv6DefaultGateway = settings.ipv6DefaultGateway; 191 }, 192 getTabIndex(selectedIndex) { 193 this.tabIndex = selectedIndex; 194 this.$store.dispatch('network/setSelectedTabIndex', this.tabIndex); 195 this.$store.dispatch( 196 'network/setSelectedTabId', 197 this.ethernetData[selectedIndex].Id, 198 ); 199 this.getModalInfo(); 200 }, 201 saveIpv4Address(modalFormData) { 202 this.startLoader(); 203 this.$store 204 .dispatch('network/saveIpv4Address', modalFormData) 205 .then((message) => this.successToast(message)) 206 .catch(({ message }) => this.errorToast(message)) 207 .finally(() => this.endLoader()); 208 }, 209 saveIpv6Address(modalFormData) { 210 this.startLoader(); 211 this.$store 212 .dispatch('network/saveIpv6Address', modalFormData) 213 .then((message) => this.successToast(message)) 214 .catch(({ message }) => this.errorToast(message)) 215 .finally(() => this.endLoader()); 216 }, 217 saveDnsAddress(modalFormData) { 218 this.startLoader(); 219 this.$store 220 .dispatch('network/saveDnsAddress', modalFormData) 221 .then((message) => this.successToast(message)) 222 .catch(({ message }) => this.errorToast(message)) 223 .finally(() => this.endLoader()); 224 }, 225 saveSettings(modalFormData) { 226 this.startLoader(); 227 this.$store 228 .dispatch('network/saveSettings', modalFormData) 229 .then((message) => this.successToast(message)) 230 .catch(({ message }) => this.errorToast(message)) 231 .finally(() => this.endLoader()); 232 }, 233 }, 234}; 235</script> 236