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