blob: 7dba367d5fd93e10fc180f9d4195ffdf42e0c31a [file] [log] [blame]
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +00001<template>
2 <b-container fluid="xl">
3 <page-title :description="$t('pageSnmpAlerts.pageDescription')" />
4 <b-row>
jason westoverd36ac8a2025-11-03 20:58:59 -06005 <b-col xl="9" class="text-end">
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +00006 <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"
jason westoverd36ac8a2025-11-03 20:58:59 -060016 :selected-items-count="
17 Array.isArray(selectedRows) ? selectedRows.length : 0
18 "
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000019 :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
jason westoverd36ac8a2025-11-03 20:58:59 -060030 thead-class="table-light"
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000031 :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"
jason westoverd36ac8a2025-11-03 20:58:59 -060042 @change="onChangeHeaderCheckbox($refs.table, $event)"
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000043 >
jason westoverd36ac8a2025-11-03 20:58:59 -060044 <span class="visually-hidden-focusable">
45 {{ $t('global.table.selectAll') }}
46 </span>
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000047 </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 >
jason westoverd36ac8a2025-11-03 20:58:59 -060055 <span class="visually-hidden-focusable">
56 {{ $t('global.table.selectItem') }}
57 </span>
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000058 </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 -->
jason westoverd36ac8a2025-11-03 20:58:59 -060081 <modal-add-destination v-model="showAddDestination" @ok="onModalOk" />
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000082 </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';
jason westoverd36ac8a2025-11-03 20:58:59 -060094import { useModal } from 'bootstrap-vue-next';
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +000095
96import BVTableSelectableMixin, {
97 selectedRows,
98 tableHeaderCheckboxModel,
99 tableHeaderCheckboxIndeterminate,
100} from '@/components/Mixins/BVTableSelectableMixin';
Surya Vde23ea22024-07-11 15:19:46 +0530101import { useI18n } from 'vue-i18n';
102import i18n from '@/i18n';
103
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000104export 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 },
jason westoverd36ac8a2025-11-03 20:58:59 -0600119 setup() {
120 const bvModal = useModal();
121 return { bvModal };
122 },
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000123 data() {
124 return {
Surya Vde23ea22024-07-11 15:19:46 +0530125 $t: useI18n().t,
jason westoverd36ac8a2025-11-03 20:58:59 -0600126 showAddDestination: false,
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000127 fields: [
128 {
129 key: 'checkbox',
130 },
131 {
132 key: 'IP',
Surya Vde23ea22024-07-11 15:19:46 +0530133 label: i18n.global.t('pageSnmpAlerts.table.ipaddress'),
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000134 },
135 {
136 key: 'Port',
Surya Vde23ea22024-07-11 15:19:46 +0530137 label: i18n.global.t('pageSnmpAlerts.table.port'),
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000138 },
139 {
140 key: 'actions',
141 label: '',
jason westoverd36ac8a2025-11-03 20:58:59 -0600142 tdClass: 'text-end text-nowrap',
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000143 },
144 ],
145 tableToolbarActions: [
146 {
147 value: 'delete',
Surya Vde23ea22024-07-11 15:19:46 +0530148 label: i18n.global.t('global.action.delete'),
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000149 },
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,
Surya Vde23ea22024-07-11 15:19:46 +0530184 title: i18n.global.t('pageSnmpAlerts.deleteDestination'),
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000185 },
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() {
jason westoverd36ac8a2025-11-03 20:58:59 -0600217 this.showAddDestination = true;
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000218 },
219 initModalDeleteDestination(destination) {
jason westoverd36ac8a2025-11-03 20:58:59 -0600220 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 });
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000237 },
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') {
jason westoverd36ac8a2025-11-03 20:58:59 -0600248 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,
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000258 ),
jason westoverd36ac8a2025-11-03 20:58:59 -0600259 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 });
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000280 }
281 },
jason westoverd36ac8a2025-11-03 20:58:59 -0600282 confirmDialog(message, options = {}) {
283 return this.$confirm({ message, ...options });
284 },
Konstantin Aladyshev7c1cfe72023-05-16 09:03:25 +0000285 onTableRowAction(action, row) {
286 if (action === 'delete') {
287 this.initModalDeleteDestination(row);
288 }
289 },
290 },
291};
292</script>