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 filteredActions(item)"
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    filteredActions() {
143      return (item) => {
144        if (item.AddressOrigin === 'DHCP') {
145          return item.actions.filter((action) => action.value !== 'delete');
146        } else {
147          return item.actions;
148        }
149      };
150    },
151  },
152  watch: {
153    // Watch for change in tab index
154    tabIndex() {
155      this.getIpv4TableItems();
156    },
157    ethernetData() {
158      this.getIpv4TableItems();
159    },
160  },
161  created() {
162    this.getIpv4TableItems();
163    this.$store.dispatch('network/getEthernetData').finally(() => {
164      // Emit initial data fetch complete to parent component
165      this.$root.$emit('network-table-ipv4-complete');
166    });
167  },
168  methods: {
169    getIpv4TableItems() {
170      const index = this.tabIndex;
171      const addresses = this.ethernetData[index].IPv4Addresses || [];
172      this.form.ipv4TableItems = addresses.map((ipv4) => {
173        return {
174          Address: ipv4.Address,
175          SubnetMask: ipv4.SubnetMask,
176          Gateway: ipv4.Gateway,
177          AddressOrigin: ipv4.AddressOrigin,
178          actions: [
179            {
180              value: 'delete',
181              title: this.$t('pageNetwork.table.deleteIpv4'),
182            },
183          ],
184        };
185      });
186    },
187    onIpv4TableAction(action, $event, index) {
188      if ($event === 'delete') {
189        this.deleteIpv4TableRow(index);
190      }
191    },
192    deleteIpv4TableRow(index) {
193      this.form.ipv4TableItems.splice(index, 1);
194      const newIpv4Array = this.form.ipv4TableItems.map((ipv4) => {
195        const { Address, SubnetMask, Gateway } = ipv4;
196        return {
197          Address,
198          SubnetMask,
199          Gateway,
200        };
201      });
202      this.$store
203        .dispatch('network/editIpv4Address', newIpv4Array)
204        .then((message) => this.successToast(message))
205        .catch(({ message }) => this.errorToast(message));
206    },
207    initAddIpv4Address() {
208      this.$bvModal.show('modal-add-ipv4');
209    },
210    changeDhcpEnabledState(state) {
211      this.$bvModal
212        .msgBoxConfirm(
213          state
214            ? this.$t('pageNetwork.modal.confirmEnableDhcp')
215            : this.$t('pageNetwork.modal.confirmDisableDhcp'),
216          {
217            title: this.$t('pageNetwork.modal.dhcpConfirmTitle', {
218              dhcpState: state
219                ? this.$t('global.action.enable')
220                : this.$t('global.action.disable'),
221            }),
222            okTitle: state
223              ? this.$t('global.action.enable')
224              : this.$t('global.action.disable'),
225            okVariant: 'danger',
226            cancelTitle: this.$t('global.action.cancel'),
227            autoFocusButton: 'cancel',
228          },
229        )
230        .then((dhcpEnableConfirmed) => {
231          if (dhcpEnableConfirmed) {
232            this.$store
233              .dispatch('network/saveDhcpEnabledState', state)
234              .then((message) => this.successToast(message))
235              .catch(({ message }) => this.errorToast(message));
236          } else {
237            let onDhcpCancel = document.getElementById('dhcpSwitch');
238            onDhcpCancel.checked = !state;
239          }
240        });
241    },
242  },
243};
244</script>
245