Skip to content

Commit 0e475e3

Browse files
aliciamatsumotoAlicia Matsumotowhitdog47
authored
(refactor) signal triggers page with entity information (#6025)
* baseline utility * first signal view refactored * put back label * prettier * docstring --------- Co-authored-by: Alicia Matsumoto <[email protected]> Co-authored-by: David Whittaker <[email protected]>
1 parent e46fa02 commit 0e475e3

File tree

2 files changed

+146
-72
lines changed

2 files changed

+146
-72
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div>
3+
<v-menu v-model="menu" origin="overlap">
4+
<template #activator="{ props }">
5+
<v-chip v-bind="props">
6+
{{ value.length }} <v-icon class="pl-2">mdi-cube-outline</v-icon>
7+
</v-chip>
8+
</template>
9+
<v-card v-if="value.length > 0" max-width="600px" class="pb-4">
10+
<v-list-dark v-bind="props">
11+
<v-list-item>
12+
<v-list-item-title>Entities</v-list-item-title>
13+
<template #append>
14+
<v-btn icon variant="text" @click="menu = false">
15+
<v-icon>mdi-close-circle</v-icon>
16+
</v-btn>
17+
</template>
18+
</v-list-item>
19+
<v-list-item v-for="entity in value" :key="`${entity.entity_type.name}-${entity.value}`">
20+
<h5>{{ entity.entity_type.name }}</h5>
21+
{{ entity.value }}
22+
</v-list-item>
23+
</v-list-dark>
24+
</v-card>
25+
</v-menu>
26+
</div>
27+
</template>
28+
29+
<script>
30+
export default {
31+
name: "InstanceEntityPopover",
32+
33+
data: () => ({
34+
menu: false,
35+
}),
36+
37+
setup() {},
38+
39+
props: {
40+
value: {
41+
type: Object,
42+
default: function () {
43+
return {}
44+
},
45+
},
46+
},
47+
}
48+
</script>

src/dispatch/static/dispatch/src/signal/TableInstance.vue

Lines changed: 98 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -8,77 +8,77 @@
88
<table-filter-dialog />
99
</v-col>
1010
</v-row>
11-
<v-row no-gutters>
12-
<v-col>
13-
<v-card variant="flat">
14-
<!-- <v-card-title> -->
15-
<!-- <v-text-field -->
16-
<!-- v-model="q" -->
17-
<!-- append-icon="search" -->
18-
<!-- label="Search" -->
19-
<!-- single-line -->
20-
<!-- hide-details -->
21-
<!-- clearable -->
22-
<!-- /> -->
23-
<!-- </v-card-title> -->
24-
<v-data-table-server
25-
:headers="headers"
26-
:items="items"
27-
:items-length="total || 0"
28-
v-model:page="page"
29-
v-model:items-per-page="itemsPerPage"
30-
:footer-props="{
31-
'items-per-page-options': [10, 25, 50, 100],
32-
}"
33-
v-model:sort-by="sortBy"
34-
v-model:sort-desc="descending"
35-
:loading="loading"
36-
loading-text="Loading... Please wait"
37-
>
38-
<template #item.case="{ value }">
39-
<case-popover v-if="value" :value="value" />
40-
</template>
41-
<template #item.signal="{ value }">
42-
<signal-popover :value="value" />
43-
</template>
44-
<template #item.signal.project.display_name="{ item, value }">
45-
<v-chip size="small" :color="item.signal.project.color">
46-
{{ value }}
47-
</v-chip>
48-
</template>
49-
<template #item.filter_action="{ value }">
50-
<v-chip
51-
size="small"
52-
:color="
53-
{
54-
snooze: 'blue-accent-4',
55-
deduplicate: 'blue-accent-2',
56-
}[value]
57-
"
58-
>
59-
{{
60-
{
61-
snooze: "Snoozed",
62-
deduplicate: "Duplicate",
63-
}[value] || "Not Filtered"
64-
}}
65-
</v-chip>
66-
</template>
67-
<template #item.created_at="{ value }">
68-
<v-tooltip location="bottom">
69-
<template #activator="{ props }">
70-
<span v-bind="props">{{ formatRelativeDate(value) }}</span>
71-
</template>
72-
<span>{{ formatDate(value) }}</span>
73-
</v-tooltip>
74-
</template>
75-
<template #item.data-table-actions="{ item }">
76-
<raw-signal-viewer :value="item.raw" />
77-
</template>
78-
</v-data-table-server>
79-
</v-card>
80-
</v-col>
81-
</v-row>
11+
<v-data-table-server
12+
:headers="headers"
13+
:items="items"
14+
:items-length="total || 0"
15+
v-model:page="page"
16+
v-model:items-per-page="itemsPerPage"
17+
:footer-props="{
18+
'items-per-page-options': [10, 25, 50, 100],
19+
}"
20+
v-model:sort-by="sortBy"
21+
v-model:sort-desc="descending"
22+
:loading="loading"
23+
loading-text="Loading... Please wait"
24+
>
25+
<template #item.case="{ value }">
26+
<case-popover v-if="value" :value="value" />
27+
</template>
28+
<template #item.signal="{ value }">
29+
<signal-popover :value="value" />
30+
</template>
31+
<template #item.entities="{ value }">
32+
<instance-entity-popover :value="value" />
33+
</template>
34+
<template #item.signal.filters="{ value }">
35+
<span
36+
v-if="
37+
this.getSnoozes(value) === 0 && this.getSnoozes(value, (count_expired = true)) === 0
38+
"
39+
>
40+
No Snoozes Created
41+
</span>
42+
<span v-else>
43+
<v-chip>{{ this.getSnoozes(value) }} Active</v-chip>
44+
<v-chip>{{ this.getSnoozes(value, (count_expired = true)) }} Expired</v-chip>
45+
</span>
46+
</template>
47+
<template #item.signal.project.display_name="{ item, value }">
48+
<v-chip size="small" :color="item.signal.project.color">
49+
{{ value }}
50+
</v-chip>
51+
</template>
52+
<template #item.filter_action="{ value }">
53+
<v-chip
54+
size="small"
55+
:color="
56+
{
57+
snooze: 'blue-accent-4',
58+
deduplicate: 'orange-darken-2',
59+
}[value] || 'green-darken-1'
60+
"
61+
>
62+
{{
63+
{
64+
snooze: "Snoozed",
65+
deduplicate: "Duplicate",
66+
}[value] || "Not Filtered"
67+
}}
68+
</v-chip>
69+
</template>
70+
<template #item.created_at="{ value }">
71+
<v-tooltip location="bottom">
72+
<template #activator="{ props }">
73+
<span v-bind="props">{{ formatRelativeDate(value) }}</span>
74+
</template>
75+
<span>{{ formatDate(value) }}</span>
76+
</v-tooltip>
77+
</template>
78+
<template #item.data-table-actions="{ item }">
79+
<raw-signal-viewer :value="item.raw" />
80+
</template>
81+
</v-data-table-server>
8282
</v-container>
8383
</template>
8484

@@ -92,6 +92,7 @@ import RawSignalViewer from "@/signal/RawSignalViewer.vue"
9292
import RouterUtils from "@/router/utils"
9393
import SignalPopover from "@/signal/SignalPopover.vue"
9494
import TableFilterDialog from "@/signal/TableFilterDialog.vue"
95+
import InstanceEntityPopover from "@/signal/InstanceEntityPopover.vue"
9596
9697
export default {
9798
name: "SignalInstanceTable",
@@ -101,14 +102,18 @@ export default {
101102
RawSignalViewer,
102103
SignalPopover,
103104
TableFilterDialog,
105+
InstanceEntityPopover,
104106
},
105107
106108
data() {
107109
return {
110+
activeView: "triggers",
108111
headers: [
109112
{ title: "Case", value: "case", sortable: false },
113+
{ title: "Status", value: "filter_action", sortable: true },
110114
{ title: "Signal Definition", value: "signal", sortable: false },
111-
{ title: "Filter Action", value: "filter_action", sortable: true },
115+
{ title: "Entities", value: "entities", sortable: true },
116+
{ title: "Snoozes", value: "signal.filters", sortable: false },
112117
{ title: "Project", value: "signal.project.display_name", sortable: true },
113118
{ title: "Created At", value: "created_at" },
114119
{ title: "", value: "data-table-actions", sortable: false, align: "end" },
@@ -149,6 +154,27 @@ export default {
149154
150155
methods: {
151156
...mapActions("signal", ["getAllInstances"]),
157+
158+
/**
159+
* Count the snooze filters for a given signal definition. Counts all
160+
* active snoozes by default, with the option to count expired snoozes instead.
161+
* @param signal_filters: The definition's filters.
162+
* @param count_expired: If true, count expired snoozes instead of active ones.
163+
*/
164+
getSnoozes(signal_filters, count_expired = false) {
165+
let snoozes = 0
166+
for (let filter of signal_filters) {
167+
if (filter.action === "snooze") {
168+
let filter_is_expired = filter.expiration && new Date() >= new Date(filter.expiration)
169+
if (!count_expired && !filter_is_expired) {
170+
snoozes++
171+
} else if (count_expired && filter_is_expired) {
172+
snoozes++
173+
}
174+
}
175+
}
176+
return snoozes
177+
},
152178
},
153179
154180
created() {

0 commit comments

Comments
 (0)