1<template> 2 <b-container fluid="xl"> 3 <page-title :description="$t('pageSnmpAlerts.pageDescription')" /> 4 <b-row> 5 <b-col xl="9" class="text-end"> 6 <b-button variant="primary" @click="initModalAddDestination"> 7 <icon-add /> 8 {{ $t('pageSnmpAlerts.addDestination') }} 9 </b-button> 10 </b-col> 11 </b-row> 12 <b-row> 13 <b-col xl="9"> 14 <table-toolbar 15 ref="toolbar" 16 :selected-items-count=" 17 Array.isArray(selectedRows) ? selectedRows.length : 0 18 " 19 :actions="tableToolbarActions" 20 @clear-selected="clearSelectedRows($refs.table)" 21 @batch-action="onBatchAction" 22 /> 23 <b-table 24 ref="table" 25 responsive="md" 26 selectable 27 show-empty 28 no-select-on-click 29 hover 30 thead-class="table-light" 31 :fields="fields" 32 :items="tableItems" 33 :empty-text="$t('global.table.emptyMessage')" 34 @row-selected="onRowSelected($event, tableItems.length)" 35 > 36 <!-- Checkbox column --> 37 <template #head(checkbox)> 38 <b-form-checkbox 39 v-model="tableHeaderCheckboxModel" 40 data-test-id="snmpAlerts-checkbox-selectAll" 41 :indeterminate="tableHeaderCheckboxIndeterminate" 42 @change="onChangeHeaderCheckbox($refs.table, $event)" 43 > 44 <span class="visually-hidden-focusable"> 45 {{ $t('global.table.selectAll') }} 46 </span> 47 </b-form-checkbox> 48 </template> 49 <template #cell(checkbox)="row"> 50 <b-form-checkbox 51 v-model="row.rowSelected" 52 :data-test-id="`snmpAlerts-checkbox-selectRow-${row.index}`" 53 @change="toggleSelectRow($refs.table, row.index)" 54 > 55 <span class="visually-hidden-focusable"> 56 {{ $t('global.table.selectItem') }} 57 </span> 58 </b-form-checkbox> 59 </template> 60 61 <!-- table actions column --> 62 <template #cell(actions)="{ item }"> 63 <table-row-action 64 v-for="(action, index) in item.actions" 65 :key="index" 66 :value="action.value" 67 :enabled="action.enabled" 68 :title="action.title" 69 :data-test-id="`snmpAlerts-button-deleteRow-${item.index}`" 70 @click-table-action="onTableRowAction($event, item)" 71 > 72 <template #icon> 73 <icon-trashcan v-if="action.value === 'delete'" /> 74 </template> 75 </table-row-action> 76 </template> 77 </b-table> 78 </b-col> 79 </b-row> 80 <!-- Modals --> 81 <modal-add-destination v-model="showAddDestination" @ok="onModalOk" /> 82 </b-container> 83</template> 84 85<script> 86import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; 87import ModalAddDestination from './ModalAddDestination'; 88import PageTitle from '@/components/Global/PageTitle'; 89import IconAdd from '@carbon/icons-vue/es/add--alt/20'; 90import TableToolbar from '@/components/Global/TableToolbar'; 91import TableRowAction from '@/components/Global/TableRowAction'; 92import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 93import BVToastMixin from '@/components/Mixins/BVToastMixin'; 94import { useModal } from 'bootstrap-vue-next'; 95 96import BVTableSelectableMixin, { 97 selectedRows, 98 tableHeaderCheckboxModel, 99 tableHeaderCheckboxIndeterminate, 100} from '@/components/Mixins/BVTableSelectableMixin'; 101import { useI18n } from 'vue-i18n'; 102import i18n from '@/i18n'; 103 104export default { 105 name: 'SnmpAlerts', 106 components: { 107 PageTitle, 108 IconAdd, 109 TableToolbar, 110 IconTrashcan, 111 ModalAddDestination, 112 TableRowAction, 113 }, 114 mixins: [BVTableSelectableMixin, BVToastMixin, LoadingBarMixin], 115 beforeRouteLeave(to, from, next) { 116 this.hideLoader(); 117 next(); 118 }, 119 setup() { 120 const bvModal = useModal(); 121 return { bvModal }; 122 }, 123 data() { 124 return { 125 $t: useI18n().t, 126 showAddDestination: false, 127 fields: [ 128 { 129 key: 'checkbox', 130 }, 131 { 132 key: 'IP', 133 label: i18n.global.t('pageSnmpAlerts.table.ipaddress'), 134 }, 135 { 136 key: 'Port', 137 label: i18n.global.t('pageSnmpAlerts.table.port'), 138 }, 139 { 140 key: 'actions', 141 label: '', 142 tdClass: 'text-end text-nowrap', 143 }, 144 ], 145 tableToolbarActions: [ 146 { 147 value: 'delete', 148 label: i18n.global.t('global.action.delete'), 149 }, 150 ], 151 selectedRows: selectedRows, 152 tableHeaderCheckboxModel: tableHeaderCheckboxModel, 153 tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, 154 }; 155 }, 156 computed: { 157 allSnmpDetails() { 158 return this.$store.getters['snmpAlerts/allSnmpDetails']; 159 }, 160 tableItems() { 161 // transform destination data to table data 162 return this.allSnmpDetails.map((subscriptions) => { 163 const [destination, dataWithProtocol, dataWithoutProtocol] = [ 164 subscriptions.Destination, 165 subscriptions.Destination.split('/')[2].split(':'), 166 subscriptions.Destination.split(':'), 167 ]; 168 //condition to check if destination comes with protocol or not 169 const conditionForProtocolCheck = destination.includes('://'); 170 const ip = conditionForProtocolCheck 171 ? dataWithProtocol[0] 172 : dataWithoutProtocol[0]; 173 const port = conditionForProtocolCheck 174 ? dataWithProtocol[1] 175 : dataWithoutProtocol[1]; 176 return { 177 IP: ip, 178 Port: port, 179 id: subscriptions.Id, 180 actions: [ 181 { 182 value: 'delete', 183 enabled: true, 184 title: i18n.global.t('pageSnmpAlerts.deleteDestination'), 185 }, 186 ], 187 ...subscriptions, 188 }; 189 }); 190 }, 191 }, 192 created() { 193 this.startLoader(); 194 this.$store 195 .dispatch('snmpAlerts/getSnmpDetails') 196 .finally(() => this.endLoader()); 197 }, 198 methods: { 199 onModalOk({ ipAddress, port }) { 200 const protocolIpAddress = 'snmp://' + ipAddress; 201 const destination = port 202 ? protocolIpAddress + ':' + port 203 : protocolIpAddress; 204 const data = { 205 Destination: destination, 206 SubscriptionType: 'SNMPTrap', 207 Protocol: 'SNMPv2c', 208 }; 209 this.startLoader(); 210 this.$store 211 .dispatch('snmpAlerts/addDestination', { data }) 212 .then((success) => this.successToast(success)) 213 .catch(({ message }) => this.errorToast(message)) 214 .finally(() => this.endLoader()); 215 }, 216 initModalAddDestination() { 217 this.showAddDestination = true; 218 }, 219 initModalDeleteDestination(destination) { 220 this.confirmDialog( 221 i18n.global.t('pageSnmpAlerts.modal.deleteConfirmMessage', { 222 destination: destination.id, 223 }), 224 { 225 title: i18n.global.t( 226 'pageSnmpAlerts.modal.deleteSnmpDestinationTitle', 227 ), 228 okTitle: i18n.global.t('pageSnmpAlerts.deleteDestination'), 229 cancelTitle: i18n.global.t('global.action.cancel'), 230 autoFocusButton: 'ok', 231 }, 232 ).then((deleteConfirmed) => { 233 if (deleteConfirmed) { 234 this.deleteDestination(destination); 235 } 236 }); 237 }, 238 deleteDestination({ id }) { 239 this.startLoader(); 240 this.$store 241 .dispatch('snmpAlerts/deleteDestination', id) 242 .then((success) => this.successToast(success)) 243 .catch(({ message }) => this.errorToast(message)) 244 .finally(() => this.endLoader()); 245 }, 246 onBatchAction(action) { 247 if (action === 'delete') { 248 const count = this.selectedRows.length; 249 this.confirmDialog( 250 i18n.global.t( 251 'pageSnmpAlerts.modal.batchDeleteConfirmMessage', 252 count, 253 ), 254 { 255 title: i18n.global.t( 256 'pageSnmpAlerts.modal.deleteSnmpDestinationTitle', 257 count, 258 ), 259 okTitle: i18n.global.t('pageSnmpAlerts.deleteDestination', count), 260 cancelTitle: i18n.global.t('global.action.cancel'), 261 autoFocusButton: 'ok', 262 }, 263 ).then((deleteConfirmed) => { 264 if (deleteConfirmed) { 265 this.startLoader(); 266 this.$store 267 .dispatch( 268 'snmpAlerts/deleteMultipleDestinations', 269 this.selectedRows, 270 ) 271 .then((messages) => { 272 messages.forEach(({ type, message }) => { 273 if (type === 'success') this.successToast(message); 274 if (type === 'error') this.errorToast(message); 275 }); 276 }) 277 .finally(() => this.endLoader()); 278 } 279 }); 280 } 281 }, 282 confirmDialog(message, options = {}) { 283 return this.$confirm({ message, ...options }); 284 }, 285 onTableRowAction(action, row) { 286 if (action === 'delete') { 287 this.initModalDeleteDestination(row); 288 } 289 }, 290 }, 291}; 292</script> 293