Skip to content

Commit

Permalink
feat: add notification delay
Browse files Browse the repository at this point in the history
  • Loading branch information
sbgap committed Jun 6, 2024
1 parent 460ec60 commit ca20df7
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,13 @@ export default {
perms: 'read:notification_channels',
show: true
},
{
icon: 'av_timer',
text: i18n.t('NotificationDelay'),
path: '/notificationdelays',
perms: 'read:notification_rules',
show: true
},
{
icon: 'notifications',
text: i18n.t('NotificationRules'),
Expand Down
159 changes: 159 additions & 0 deletions src/components/NotificationDelayList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<template>
<div>
<v-card>
<v-card-title class="title">
{{ $t('notificationDelays') }}
</v-card-title>

<v-data-table
:headers="computedHeaders"
:items="notification_delays"
:pagination.sync="pagination"
:total-items="pagination.totalItems"
:rows-per-page-items="pagination.rowsPerPageItems"
class="px-2"
:loading="false"
must-sort
sort-icon="arrow_drop_down"
>
<template
slot="items"
slot-scope="props"
>
<td>{{ props.item.alert_id }}</td>
<td>{{ props.item.notification_rule_id }}</td>
<td>{{ props.item.delay_time }}</td>
<td class="text-no-wrap">
<v-btn
v-has-perms.disable="'write:notification_rules'"
icon
class="btn--plain mx-0"
@click="deleteItem(props.item)"
>
<v-icon
small
color="grey darken-3"
>
delete
</v-icon>
</v-btn>
</td>
</template>
<template slot="no-data">
<v-alert
:value="true"
color="error"
icon="warning"
>
{{ $t('NoDisplay') }}
</v-alert>
</template>
</v-data-table>
</v-card>
</div>
</template>

<script>
import ListButtonAdd from './lib/ListButtonAdd'
import moment from 'moment'
import i18n from '@/plugins/i18n'
export default {
data: vm => ({
headers: [
{ text: i18n.t('Alert'), value: 'alert_id' },
{ text: i18n.t('NotificationRule'), value: 'notification_rule_id' },
{ text: i18n.t('Time'), value: 'delay_time' },
],
timer: null
}),
computed: {
notification_delays() {
return this.$store.state.notificationDelays.notification_delays
.map(b => {
let delay_time = b.delay_time ? moment(b.delay_time).format('YYYY-MM-DD HH:mm:ss') : null
return Object.assign(
{ ...b, delay_time },
)
})
},
pagination: {
get() {
return this.$store.getters['notificationDelays/pagination']
},
set(value) {
this.$store.dispatch('notificationDelays/setPagination', value)
}
},
computedHeaders() {
return this.headers.filter(h =>
!this.$config.customer_views ? h.value != 'customer' : true
)
},
isLoading() {
return this.$store.state.notificationDelays.isLoading
},
refresh() {
return this.$store.state.refresh
},
refreshInterval() {
return (
this.$store.getters.getPreference('refreshInterval') ||
this.$store.getters.getConfig('refresh_interval')
)
},
},
watch: {
refresh(val) {
if (val) return
this.getNotificationDelays()
},
pagination: {
handler() {
this.getNotificationDelays()
},
deep: true
}
},
created() {
this.cancelTimer()
this.refreshDelays()
},
beforeDestroy() {
this.cancelTimer()
},
methods: {
getNotificationDelays() {
return this.$store.dispatch('notificationDelays/getNotificationDelays')
},
deleteItem(item) {
confirm(i18n.t('ConfirmDelete')) &&
this.$store.dispatch(
'notificationDelays/deleteNotificationDelay',
item.id
)
},
cancelTimer() {
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
},
refreshDelays() {
this.getNotificationDelays()
.then(() => {
this.timer = setTimeout(() => this.refreshDelays(), this.refresh_interval)
})
},
refresh_all() {
this.$store.dispatch('set', ['refresh', true])
setTimeout(() => {
this.$store.dispatch('set', ['refresh', false])
}, 300)
}
}
}
</script>

<style></style>
32 changes: 32 additions & 0 deletions src/components/NotificationRuleList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,20 @@
required
/>
</v-flex>

<v-flex xs8>
<v-text-field
v-model.trim="editedItem.timeObj.time"
:label="$t('DelayTime')"
/>
</v-flex>
<v-flex xs4>
<v-select
v-model="editedItem.timeObj.interval"
:items="intervals"
:label="$t('Interval')"
/>
</v-flex>

<v-flex
xs12
Expand Down Expand Up @@ -572,6 +586,7 @@
<td v-if="$config.customer_views">
{{ props.item.customer }}
</td>
<td>{{ props.item.delayTime }}</td>
<td>{{ props.item.name }}</td>
<td>{{ props.item.environment }}</td>
<td>{{ props.item.reactivateDate }} {{ props.item.reactivateTime }}</td>
Expand Down Expand Up @@ -747,12 +762,14 @@ export default {
data: vm => ({
status: ['true', 'false'],
days: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
intervals: ['second','minute', 'hour', 'days'],
search: '',
dialog: false,
active_dialog: false,
headers: [
{ text: i18n.t('Acitve'), value: 'active' },
{ text: i18n.t('Customer'), value: 'customer' },
{ text: i18n.t('Delay'), value: 'delay' },
{ text: i18n.t('Name'), value: 'Name' },
{ text: i18n.t('Environment'), value: 'environment' },
{ text: i18n.t('Reactivate'), value: 'reactivate' },
Expand Down Expand Up @@ -780,6 +797,10 @@ export default {
customer: null,
name: null,
environment: null,
timeObj: {
time: null,
interval: null
},
receivers: [],
userIds: [],
groupIds: [],
Expand Down Expand Up @@ -811,6 +832,10 @@ export default {
customer: null,
name: null,
environment: null,
timeObj: {
time: null,
interval: null
},
receivers: [],
userIds: [],
groupIds: [],
Expand Down Expand Up @@ -867,11 +892,16 @@ export default {
).slice(-2)}`
}
let reactivate = b.reactivate ? moment(b.reactivate) : null
return Object.assign(
{ ...b },
{
period: period,
timeObj: {
time: b.delayTime,
interval: 'second'
},
text:
b.text === null
? ''
Expand Down Expand Up @@ -1135,6 +1165,7 @@ export default {
customer: this.editedItem.customer,
name: this.editedItem.name,
environment: this.editedItem.environment,
delayTime: this.editedItem.timeObj.time ? `${this.editedItem.timeObj.time} ${this.editedItem.timeObj.interval}` : null,
receivers: this.editedItem.receivers,
userIds: this.editedItem.userIds,
groupIds: this.editedItem.groupIds,
Expand Down Expand Up @@ -1167,6 +1198,7 @@ export default {
id: null,
startTime: sTimeStr,
endTime: eTimeStr,
delayTime: this.editedItem.timeObj.time ? `${this.editedItem.timeObj.time} ${this.editedItem.timeObj.interval}` : null,
text: this.editedItem.text.replace(/\{([\w\[\]\. ]*)\}/g, '%($1)s')
})
)
Expand Down
6 changes: 6 additions & 0 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ export function createRouter(basePath): VueRouter {
component: () => import(/* webpackChunkName: 'user' */ './views/Blackouts.vue'),
meta: {title: 'Blackouts', requiresAuth: true}
},
{
path: '/notificationdelays',
name: 'notificationdelays',
component: () => import(/* webpackChunkName: 'user' */ './views/NotificationDelay.vue'),
meta: {title: 'NotificationDelays', requiresAuth: true}
},
{
path: '/notificationrules',
name: 'notificationrules',
Expand Down
13 changes: 13 additions & 0 deletions src/services/api/notificationDelay.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import api from './index'

export default {
getNotificationDelays(query: object) {
let config = {
params: {}
}
return api.get('/notificationdelay', config)
},
deleteNotificationDelay(id: string) {
return api.delete(`/notificationdelay/${id}`)
}
}
2 changes: 2 additions & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import heartbeats from './modules/heartbeats.store'
import blackouts from './modules/blackouts.store'
import notificationRules from './modules/notificationRule.store'
import notificationHistory from './modules/notificationHistory.store'
import notificationDelays from './modules/notificationDelay.store'
import escalationRules from './modules/escalationRule.store'
import notificationChannels from './modules/notificationChannel.store'
import onCalls from './modules/onCall.store'
Expand Down Expand Up @@ -51,6 +52,7 @@ export function createStore(): Store<any> {
heartbeats,
blackouts,
notificationRules,
notificationDelays,
notificationHistory,
escalationRules,
notificationChannels,
Expand Down
77 changes: 77 additions & 0 deletions src/store/modules/notificationDelay.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import NotificationDelayApi from '@/services/api/notificationDelay.service'

const namespaced = true

const state = {
isLoading: false,

notification_delays: [],

pagination: {
page: 1,
rowsPerPage: 15,
sortBy: 'delay_time',
descending: true,
rowsPerPageItems: [10, 15, 30, 50, 100, 200]
}
}

const mutations = {
SET_LOADING(state) {
state.isLoading = true
},
SET_NOTIFICATION_DELAY(state, [notificationDelays, total, pageSize]) {
state.isLoading = false
state.notification_delays = notificationDelays
state.pagination.totalItems = total
state.pagination.rowsPerPage = pageSize
},
RESET_LOADING(state) {
state.isLoading = false
},
SET_PAGINATION(state, pagination) {
state.pagination = Object.assign({}, state.pagination, pagination)
}
}

const actions = {
getNotificationDelays({commit, state}) {
commit('SET_LOADING')
let params = new URLSearchParams()

// add server-side paging
params.append('page', state.pagination.page)
params.append('page-size', state.pagination.rowsPerPage)

// add server-side sort
params.append('sort-by', (state.pagination.descending ? '-' : '') + state.pagination.sortBy)

return NotificationDelayApi.getNotificationDelays(params)
.then(({notificationDelays, total, pageSize}) =>
commit('SET_NOTIFICATION_DELAY', [notificationDelays, total, pageSize])
)
.catch(() => commit('RESET_LOADING'))
},
deleteNotificationDelay({dispatch, commit}, notificationDelayId) {
return NotificationDelayApi.deleteNotificationDelay(notificationDelayId).then(response => {
dispatch('getNotificationDelays')
})
},
setPagination({commit}, pagination) {
commit('SET_PAGINATION', pagination)
}
}

const getters = {
pagination: state => {
return state.pagination
}
}

export default {
namespaced,
state,
mutations,
actions,
getters
}
Loading

0 comments on commit ca20df7

Please sign in to comment.