1db47b7e1SSean Zhang<template> 2db47b7e1SSean Zhang <page-section :section-title="$t('pageNetwork.ipv6')"> 3db47b7e1SSean Zhang <b-row class="mb-4"> 4db47b7e1SSean Zhang <b-col lg="2" md="6"> 5db47b7e1SSean Zhang <dl> 6db47b7e1SSean Zhang <dt>{{ $t('pageNetwork.dhcp6') }}</dt> 7db47b7e1SSean Zhang <dd> 8db47b7e1SSean Zhang <b-form-checkbox 9db47b7e1SSean Zhang id="dhcp6Switch" 10db47b7e1SSean Zhang v-model="dhcp6EnabledState" 11db47b7e1SSean Zhang data-test-id="networkSettings-switch-dhcp6Enabled" 12db47b7e1SSean Zhang switch 13db47b7e1SSean Zhang @change="changeDhcp6EnabledState" 14db47b7e1SSean Zhang > 15db47b7e1SSean Zhang <span v-if="dhcp6EnabledState"> 16db47b7e1SSean Zhang {{ $t('global.status.enabled') }} 17db47b7e1SSean Zhang </span> 18db47b7e1SSean Zhang <span v-else>{{ $t('global.status.disabled') }}</span> 19db47b7e1SSean Zhang </b-form-checkbox> 20db47b7e1SSean Zhang </dd> 21db47b7e1SSean Zhang </dl> 22db47b7e1SSean Zhang </b-col> 23db47b7e1SSean Zhang <b-col lg="2" md="6"> 24db47b7e1SSean Zhang <dl class="text-nowrap"> 25db47b7e1SSean Zhang <dt> 26db47b7e1SSean Zhang {{ $t('pageNetwork.ipv6DefaultGateway') }} 27db47b7e1SSean Zhang <b-button 28db47b7e1SSean Zhang v-if="defaultGatewayEditable" 29db47b7e1SSean Zhang variant="link" 30db47b7e1SSean Zhang class="p-1" 31db47b7e1SSean Zhang @click="initDefaultGatewayModal()" 32db47b7e1SSean Zhang > 33db47b7e1SSean Zhang <icon-edit 34db47b7e1SSean Zhang :title="$t('pageNetwork.modal.editIPv6DefaultGatewayTitle')" 35db47b7e1SSean Zhang /> 36db47b7e1SSean Zhang </b-button> 37db47b7e1SSean Zhang </dt> 38db47b7e1SSean Zhang <dd> 39db47b7e1SSean Zhang {{ dataFormatter(defaultGateway) }} 40db47b7e1SSean Zhang </dd> 41db47b7e1SSean Zhang </dl> 42db47b7e1SSean Zhang </b-col> 43db47b7e1SSean Zhang </b-row> 44db47b7e1SSean Zhang <b-row> 45db47b7e1SSean Zhang <b-col> 46db47b7e1SSean Zhang <h3 class="h5"> 47db47b7e1SSean Zhang {{ $t('pageNetwork.ipv6Addresses') }} 48db47b7e1SSean Zhang </h3> 49db47b7e1SSean Zhang </b-col> 50db47b7e1SSean Zhang <b-col class="text-right"> 51db47b7e1SSean Zhang <b-button variant="primary" @click="initAddIpv6Address()"> 52db47b7e1SSean Zhang <icon-add /> 53db47b7e1SSean Zhang {{ $t('pageNetwork.table.addIpv6Address') }} 54db47b7e1SSean Zhang </b-button> 55db47b7e1SSean Zhang </b-col> 56db47b7e1SSean Zhang </b-row> 57db47b7e1SSean Zhang <b-table 58db47b7e1SSean Zhang responsive="md" 59db47b7e1SSean Zhang hover 60db47b7e1SSean Zhang :fields="ipv6TableFields" 61db47b7e1SSean Zhang :items="form.ipv6TableItems" 62db47b7e1SSean Zhang :empty-text="$t('global.table.emptyMessage')" 63db47b7e1SSean Zhang class="mb-0" 64db47b7e1SSean Zhang show-empty 65db47b7e1SSean Zhang > 66db47b7e1SSean Zhang <template #cell(actions)="{ item, index }"> 67db47b7e1SSean Zhang <table-row-action 68db47b7e1SSean Zhang v-for="(action, actionIndex) in filteredActions(item)" 69db47b7e1SSean Zhang :key="actionIndex" 70db47b7e1SSean Zhang :value="action.value" 71db47b7e1SSean Zhang :title="action.title" 72db47b7e1SSean Zhang :enabled="action.enabled" 73db47b7e1SSean Zhang @click-table-action="onIpv6TableAction(action, $event, index)" 74db47b7e1SSean Zhang > 75db47b7e1SSean Zhang <template #icon> 76db47b7e1SSean Zhang <icon-edit v-if="action.value === 'edit'" /> 77db47b7e1SSean Zhang <icon-trashcan v-if="action.value === 'delete'" /> 78db47b7e1SSean Zhang </template> 79db47b7e1SSean Zhang </table-row-action> 80db47b7e1SSean Zhang </template> 81db47b7e1SSean Zhang </b-table> 82db47b7e1SSean Zhang </page-section> 83db47b7e1SSean Zhang</template> 84db47b7e1SSean Zhang 85db47b7e1SSean Zhang<script> 86db47b7e1SSean Zhangimport BVToastMixin from '@/components/Mixins/BVToastMixin'; 87db47b7e1SSean Zhangimport IconAdd from '@carbon/icons-vue/es/add--alt/20'; 88db47b7e1SSean Zhangimport IconEdit from '@carbon/icons-vue/es/edit/20'; 89db47b7e1SSean Zhangimport IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; 90db47b7e1SSean Zhangimport LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 91db47b7e1SSean Zhangimport PageSection from '@/components/Global/PageSection'; 92db47b7e1SSean Zhangimport TableRowAction from '@/components/Global/TableRowAction'; 93db47b7e1SSean Zhangimport DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; 94db47b7e1SSean Zhangimport { mapState } from 'vuex'; 95*4626aec4SSurya Venkatesanimport i18n from '@/i18n'; 96*4626aec4SSurya Venkatesanimport { useI18n } from 'vue-i18n'; 97db47b7e1SSean Zhang 98db47b7e1SSean Zhangexport default { 99db47b7e1SSean Zhang name: 'Ipv6Table', 100db47b7e1SSean Zhang components: { 101db47b7e1SSean Zhang IconAdd, 102db47b7e1SSean Zhang IconEdit, 103db47b7e1SSean Zhang IconTrashcan, 104db47b7e1SSean Zhang PageSection, 105db47b7e1SSean Zhang TableRowAction, 106db47b7e1SSean Zhang }, 107db47b7e1SSean Zhang mixins: [BVToastMixin, LoadingBarMixin, DataFormatterMixin], 108db47b7e1SSean Zhang props: { 109db47b7e1SSean Zhang tabIndex: { 110db47b7e1SSean Zhang type: Number, 111db47b7e1SSean Zhang default: 0, 112db47b7e1SSean Zhang }, 113db47b7e1SSean Zhang }, 114db47b7e1SSean Zhang data() { 115db47b7e1SSean Zhang return { 116*4626aec4SSurya Venkatesan $t: useI18n().t, 117db47b7e1SSean Zhang form: { 118db47b7e1SSean Zhang ipv6TableItems: [], 119db47b7e1SSean Zhang }, 120db47b7e1SSean Zhang actions: [ 121db47b7e1SSean Zhang { 122db47b7e1SSean Zhang value: 'edit', 123*4626aec4SSurya Venkatesan title: i18n.global.t('global.action.edit'), 124db47b7e1SSean Zhang }, 125db47b7e1SSean Zhang { 126db47b7e1SSean Zhang value: 'delete', 127*4626aec4SSurya Venkatesan title: i18n.global.t('global.action.delete'), 128db47b7e1SSean Zhang }, 129db47b7e1SSean Zhang ], 130db47b7e1SSean Zhang ipv6TableFields: [ 131db47b7e1SSean Zhang { 132db47b7e1SSean Zhang key: 'Address', 133*4626aec4SSurya Venkatesan label: i18n.global.t('pageNetwork.table.ipAddress'), 134db47b7e1SSean Zhang }, 135db47b7e1SSean Zhang { 136db47b7e1SSean Zhang key: 'PrefixLength', 137*4626aec4SSurya Venkatesan label: i18n.global.t('pageNetwork.table.prefixLength'), 138db47b7e1SSean Zhang }, 139db47b7e1SSean Zhang { 140db47b7e1SSean Zhang key: 'AddressOrigin', 141*4626aec4SSurya Venkatesan label: i18n.global.t('pageNetwork.table.addressOrigin'), 142db47b7e1SSean Zhang }, 143db47b7e1SSean Zhang { key: 'actions', label: '', tdClass: 'text-right' }, 144db47b7e1SSean Zhang ], 145db47b7e1SSean Zhang defaultGateway: '', 146db47b7e1SSean Zhang defaultGatewayEditable: 147db47b7e1SSean Zhang process.env.VUE_APP_ENV_NAME !== 'nvidia-bluefield', 148db47b7e1SSean Zhang }; 149db47b7e1SSean Zhang }, 150db47b7e1SSean Zhang computed: { 151db47b7e1SSean Zhang ...mapState('network', ['ethernetData']), 152db47b7e1SSean Zhang selectedInterface() { 153db47b7e1SSean Zhang return this.$store.getters['network/selectedInterfaceIndex']; 154db47b7e1SSean Zhang }, 155db47b7e1SSean Zhang dhcp6EnabledState: { 156db47b7e1SSean Zhang get() { 157db47b7e1SSean Zhang return ( 158db47b7e1SSean Zhang this.$store.getters['network/globalNetworkSettings'][ 159db47b7e1SSean Zhang this.selectedInterface 160db47b7e1SSean Zhang ].dhcp6Enabled === 'Enabled' 161db47b7e1SSean Zhang ); 162db47b7e1SSean Zhang }, 163db47b7e1SSean Zhang set(newValue) { 164db47b7e1SSean Zhang return newValue; 165db47b7e1SSean Zhang }, 166db47b7e1SSean Zhang }, 167db47b7e1SSean Zhang filteredActions() { 168db47b7e1SSean Zhang return (item) => { 169db47b7e1SSean Zhang if (item.AddressOrigin === 'DHCPv6' || item.AddressOrigin === 'SLAAC') { 170db47b7e1SSean Zhang return item.actions.filter((action) => action.value !== 'delete'); 171db47b7e1SSean Zhang } else { 172db47b7e1SSean Zhang return item.actions; 173db47b7e1SSean Zhang } 174db47b7e1SSean Zhang }; 175db47b7e1SSean Zhang }, 176db47b7e1SSean Zhang }, 177db47b7e1SSean Zhang watch: { 178db47b7e1SSean Zhang // Watch for change in tab index 179db47b7e1SSean Zhang tabIndex() { 180db47b7e1SSean Zhang this.getIpv6TableItems(); 181db47b7e1SSean Zhang this.getDefaultGateway(); 182db47b7e1SSean Zhang }, 183db47b7e1SSean Zhang ethernetData() { 184db47b7e1SSean Zhang this.getIpv6TableItems(); 185db47b7e1SSean Zhang this.getDefaultGateway(); 186db47b7e1SSean Zhang }, 187db47b7e1SSean Zhang }, 188db47b7e1SSean Zhang created() { 189db47b7e1SSean Zhang this.getIpv6TableItems(); 190db47b7e1SSean Zhang this.getDefaultGateway(); 191db47b7e1SSean Zhang this.$store.dispatch('network/getEthernetData').finally(() => { 192db47b7e1SSean Zhang // Emit initial data fetch complete to parent component 193db47b7e1SSean Zhang this.$root.$emit('network-table-ipv6-complete'); 194db47b7e1SSean Zhang }); 195db47b7e1SSean Zhang }, 196db47b7e1SSean Zhang methods: { 197db47b7e1SSean Zhang getDefaultGateway() { 198db47b7e1SSean Zhang this.defaultGateway = this.ethernetData[this.tabIndex].IPv6DefaultGateway; 199db47b7e1SSean Zhang }, 200db47b7e1SSean Zhang getIpv6TableItems() { 201db47b7e1SSean Zhang const index = this.tabIndex; 202db47b7e1SSean Zhang const addresses = 203db47b7e1SSean Zhang this.ethernetData[index].IPv6Addresses.filter( 204db47b7e1SSean Zhang (ipv6) => 205db47b7e1SSean Zhang ipv6.AddressOrigin === 'LinkLocal' || 206db47b7e1SSean Zhang ipv6.AddressOrigin === 'Static' || 207db47b7e1SSean Zhang ipv6.AddressOrigin === 'SLAAC' || 208db47b7e1SSean Zhang ipv6.AddressOrigin === 'DHCPv6', 209db47b7e1SSean Zhang ) || []; 210db47b7e1SSean Zhang this.form.ipv6TableItems = addresses.map((ipv6) => { 211db47b7e1SSean Zhang return { 212db47b7e1SSean Zhang Address: ipv6.Address, 213db47b7e1SSean Zhang PrefixLength: ipv6.PrefixLength, 214db47b7e1SSean Zhang AddressOrigin: ipv6.AddressOrigin, 215db47b7e1SSean Zhang actions: [ 216db47b7e1SSean Zhang { 217db47b7e1SSean Zhang value: 'delete', 218*4626aec4SSurya Venkatesan title: i18n.global.t('pageNetwork.table.deleteIpv6'), 219db47b7e1SSean Zhang }, 220db47b7e1SSean Zhang ], 221db47b7e1SSean Zhang }; 222db47b7e1SSean Zhang }); 223db47b7e1SSean Zhang }, 224db47b7e1SSean Zhang onIpv6TableAction(action, $event, index) { 225db47b7e1SSean Zhang if ($event === 'delete') { 226db47b7e1SSean Zhang this.deleteIpv6TableRow(index); 227db47b7e1SSean Zhang } 228db47b7e1SSean Zhang }, 229db47b7e1SSean Zhang deleteIpv6TableRow(index) { 230db47b7e1SSean Zhang const AddressOrigin = this.form.ipv6TableItems[index].AddressOrigin; 231db47b7e1SSean Zhang this.form.ipv6TableItems.splice(index, 1); 232db47b7e1SSean Zhang const newIpv6Array = this.form.ipv6TableItems.map((ipv6) => { 233db47b7e1SSean Zhang const { Address, PrefixLength } = ipv6; 234db47b7e1SSean Zhang return { 235db47b7e1SSean Zhang Address, 236db47b7e1SSean Zhang PrefixLength, 237db47b7e1SSean Zhang }; 238db47b7e1SSean Zhang }); 239db47b7e1SSean Zhang if ( 240db47b7e1SSean Zhang newIpv6Array.length == 0 && 241db47b7e1SSean Zhang (AddressOrigin === 'Static' || AddressOrigin === 'LinkLocal') 242db47b7e1SSean Zhang ) { 243db47b7e1SSean Zhang this.$store 244db47b7e1SSean Zhang .dispatch('network/saveDhcp6EnabledState', true) 245db47b7e1SSean Zhang .then((message) => this.successToast(message)) 246db47b7e1SSean Zhang .catch(({ message }) => this.errorToast(message)); 247db47b7e1SSean Zhang } 248db47b7e1SSean Zhang this.$store 249db47b7e1SSean Zhang .dispatch('network/editIpv6Address', newIpv6Array) 250db47b7e1SSean Zhang .then((message) => this.successToast(message)) 251db47b7e1SSean Zhang .catch(({ message }) => this.errorToast(message)); 252db47b7e1SSean Zhang }, 253db47b7e1SSean Zhang initAddIpv6Address() { 254db47b7e1SSean Zhang this.$bvModal.show('modal-add-ipv6'); 255db47b7e1SSean Zhang }, 256db47b7e1SSean Zhang changeDhcp6EnabledState(state) { 257db47b7e1SSean Zhang this.$bvModal 258db47b7e1SSean Zhang .msgBoxConfirm( 259db47b7e1SSean Zhang state 260*4626aec4SSurya Venkatesan ? i18n.global.t('pageNetwork.modal.confirmEnableDhcp') 261*4626aec4SSurya Venkatesan : i18n.global.t('pageNetwork.modal.confirmDisableDhcp'), 262db47b7e1SSean Zhang { 263*4626aec4SSurya Venkatesan title: i18n.global.t('pageNetwork.modal.dhcpConfirmTitle', { 264db47b7e1SSean Zhang dhcpState: state 265*4626aec4SSurya Venkatesan ? i18n.global.t('global.action.enable') 266*4626aec4SSurya Venkatesan : i18n.global.t('global.action.disable'), 267db47b7e1SSean Zhang }), 268db47b7e1SSean Zhang okTitle: state 269*4626aec4SSurya Venkatesan ? i18n.global.t('global.action.enable') 270*4626aec4SSurya Venkatesan : i18n.global.t('global.action.disable'), 271db47b7e1SSean Zhang okVariant: 'danger', 272*4626aec4SSurya Venkatesan cancelTitle: i18n.global.t('global.action.cancel'), 273db47b7e1SSean Zhang }, 274db47b7e1SSean Zhang ) 275db47b7e1SSean Zhang .then((dhcpEnableConfirmed) => { 276db47b7e1SSean Zhang if (dhcpEnableConfirmed) { 277db47b7e1SSean Zhang this.$store 278db47b7e1SSean Zhang .dispatch('network/saveDhcp6EnabledState', state) 279db47b7e1SSean Zhang .then((message) => this.successToast(message)) 280db47b7e1SSean Zhang .catch(({ message }) => this.errorToast(message)); 281db47b7e1SSean Zhang } else { 282db47b7e1SSean Zhang let onDhcpCancel = document.getElementById('dhcp6Switch'); 283db47b7e1SSean Zhang onDhcpCancel.checked = !state; 284db47b7e1SSean Zhang } 285db47b7e1SSean Zhang }); 286db47b7e1SSean Zhang }, 287db47b7e1SSean Zhang initDefaultGatewayModal() { 288db47b7e1SSean Zhang this.$bvModal.show('modal-default-gateway'); 289db47b7e1SSean Zhang }, 290db47b7e1SSean Zhang }, 291db47b7e1SSean Zhang}; 292db47b7e1SSean Zhang</script> 293