1<template>
2  <page-section :section-title="$t('pageNetwork.ipv4')">
3    <b-row class="mb-4">
4      <b-col lg="2" md="6">
5        <dl>
6          <dt>{{ $t('pageNetwork.dhcp') }}</dt>
7          <dd>
8            <b-form-checkbox
9              id="dhcpSwitch"
10              v-model="dhcpEnabledState"
11              data-test-id="networkSettings-switch-dhcpEnabled"
12              switch
13              @change="changeDhcpEnabledState"
14            >
15              <span v-if="dhcpEnabledState">
16                {{ $t('global.status.enabled') }}
17              </span>
18              <span v-else>{{ $t('global.status.disabled') }}</span>
19            </b-form-checkbox>
20          </dd>
21        </dl>
22      </b-col>
23    </b-row>
24    <b-row>
25      <b-col>
26        <h3 class="h5">
27          {{ $t('pageNetwork.ipv4Addresses') }}
28        </h3>
29      </b-col>
30      <b-col class="text-right">
31        <b-button variant="primary" @click="initAddIpv4Address()">
32          <icon-add />
33          {{ $t('pageNetwork.table.addIpv4Address') }}
34        </b-button>
35      </b-col>
36    </b-row>
37    <b-table
38      responsive="md"
39      hover
40      :fields="ipv4TableFields"
41      :items="form.ipv4TableItems"
42      :empty-text="$t('global.table.emptyMessage')"
43      class="mb-0"
44      show-empty
45    >
46      <template #cell(actions)="{ item, index }">
47        <table-row-action
48          v-for="(action, actionIndex) in item.actions"
49          :key="actionIndex"
50          :value="action.value"
51          :title="action.title"
52          :enabled="action.enabled"
53          @click-table-action="onIpv4TableAction(action, $event, index)"
54        >
55          <template #icon>
56            <icon-edit v-if="action.value === 'edit'" />
57            <icon-trashcan v-if="action.value === 'delete'" />
58          </template>
59        </table-row-action>
60      </template>
61    </b-table>
62  </page-section>
63</template>
64
65<script>
66import BVToastMixin from '@/components/Mixins/BVToastMixin';
67import IconAdd from '@carbon/icons-vue/es/add--alt/20';
68import IconEdit from '@carbon/icons-vue/es/edit/20';
69import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
70import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
71import PageSection from '@/components/Global/PageSection';
72import TableRowAction from '@/components/Global/TableRowAction';
73import { mapState } from 'vuex';
74
75export default {
76  name: 'Ipv4Table',
77  components: {
78    IconAdd,
79    IconEdit,
80    IconTrashcan,
81    PageSection,
82    TableRowAction,
83  },
84  mixins: [BVToastMixin, LoadingBarMixin],
85  props: {
86    tabIndex: {
87      type: Number,
88      default: 0,
89    },
90  },
91  data() {
92    return {
93      form: {
94        ipv4TableItems: [],
95      },
96      actions: [
97        {
98          value: 'edit',
99          title: this.$t('global.action.edit'),
100        },
101        {
102          value: 'delete',
103          title: this.$t('global.action.delete'),
104        },
105      ],
106      ipv4TableFields: [
107        {
108          key: 'Address',
109          label: this.$t('pageNetwork.table.ipAddress'),
110        },
111        {
112          key: 'Gateway',
113          label: this.$t('pageNetwork.table.gateway'),
114        },
115        {
116          key: 'SubnetMask',
117          label: this.$t('pageNetwork.table.subnet'),
118        },
119        {
120          key: 'AddressOrigin',
121          label: this.$t('pageNetwork.table.addressOrigin'),
122        },
123        { key: 'actions', label: '', tdClass: 'text-right' },
124      ],
125    };
126  },
127  computed: {
128    ...mapState('network', ['ethernetData']),
129    selectedInterface() {
130      return this.$store.getters['network/selectedInterfaceIndex'];
131    },
132    dhcpEnabledState: {
133      get() {
134        return this.$store.getters['network/globalNetworkSettings'][
135          this.selectedInterface
136        ].dhcpEnabled;
137      },
138      set(newValue) {
139        return newValue;
140      },
141    },
142  },
143  watch: {
144    // Watch for change in tab index
145    tabIndex() {
146      this.getIpv4TableItems();
147    },
148    ethernetData() {
149      this.getIpv4TableItems();
150    },
151  },
152  created() {
153    this.getIpv4TableItems();
154    this.$store.dispatch('network/getEthernetData').finally(() => {
155      // Emit initial data fetch complete to parent component
156      this.$root.$emit('network-table-ipv4-complete');
157    });
158  },
159  methods: {
160    getIpv4TableItems() {
161      const index = this.tabIndex;
162      const addresses = this.ethernetData[index].IPv4Addresses || [];
163      this.form.ipv4TableItems = addresses.map((ipv4) => {
164        return {
165          Address: ipv4.Address,
166          SubnetMask: ipv4.SubnetMask,
167          Gateway: ipv4.Gateway,
168          AddressOrigin: ipv4.AddressOrigin,
169          actions: [
170            {
171              value: 'delete',
172              title: this.$t('pageNetwork.table.deleteIpv4'),
173            },
174          ],
175        };
176      });
177    },
178    onIpv4TableAction(action, $event, index) {
179      if ($event === 'delete') {
180        this.deleteIpv4TableRow(index);
181      }
182    },
183    deleteIpv4TableRow(index) {
184      this.form.ipv4TableItems.splice(index, 1);
185      const newIpv4Array = this.form.ipv4TableItems.map((ipv4) => {
186        const { Address, SubnetMask, Gateway } = ipv4;
187        return {
188          Address,
189          SubnetMask,
190          Gateway,
191        };
192      });
193      this.$store
194        .dispatch('network/editIpv4Address', newIpv4Array)
195        .then((message) => this.successToast(message))
196        .catch(({ message }) => this.errorToast(message));
197    },
198    initAddIpv4Address() {
199      this.$bvModal.show('modal-add-ipv4');
200    },
201    changeDhcpEnabledState(state) {
202      this.$bvModal
203        .msgBoxConfirm(
204          state
205            ? this.$t('pageNetwork.modal.confirmEnableDhcp')
206            : this.$t('pageNetwork.modal.confirmDisableDhcp'),
207          {
208            title: this.$t('pageNetwork.modal.dhcpConfirmTitle', {
209              dhcpState: state
210                ? this.$t('global.action.enable')
211                : this.$t('global.action.disable'),
212            }),
213            okTitle: state
214              ? this.$t('global.action.enable')
215              : this.$t('global.action.disable'),
216            okVariant: 'danger',
217            cancelTitle: this.$t('global.action.cancel'),
218          }
219        )
220        .then((dhcpEnableConfirmed) => {
221          if (dhcpEnableConfirmed) {
222            this.$store
223              .dispatch('network/saveDhcpEnabledState', state)
224              .then((message) => this.successToast(message))
225              .catch(({ message }) => this.errorToast(message));
226          } else {
227            let onDhcpCancel = document.getElementById('dhcpSwitch');
228            onDhcpCancel.checked = !state;
229          }
230        });
231    },
232  },
233};
234</script>
235