Skip to content

Commit

Permalink
feat: added filtering for missing tables
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaile committed Dec 3, 2024
1 parent 61f8807 commit 586c8c5
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 223 deletions.
181 changes: 0 additions & 181 deletions src/components/standalone/monitoring/FilteredTraffic.vue

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/standalone/monitoring/TrafficCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const pieLabels = computed(() => {

<template>
<NeCard v-if="data" :title="title">
<div v-if="data.length > 0" class="space-y-4">
<div v-if="data.length > 0" class="space-y-6">
<BasicPieChart :datasets="pieDatasets" :labels="pieLabels" byteFormat height="25vh" />
<TrafficTable
:filterable="filterable"
Expand Down
153 changes: 119 additions & 34 deletions src/components/standalone/monitoring/TrafficMonitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,86 @@ import { useThemeStore } from '@/stores/theme'
import { useTrafficStats } from '@/composables/useTrafficStats'
import TrafficCard from '@/components/standalone/monitoring/TrafficCard.vue'
import { faEmptySet } from '@nethesis/nethesis-solid-svg-icons'
import FilteredTraffic from '@/components/standalone/monitoring/FilteredTraffic.vue'
import { useTrafficFilter } from '@/composables/useTrafficFilter'
import { type AvailableFilters, useTrafficFilter } from '@/composables/useTrafficFilter'
import NeBreadcrumbs, { type BreadcrumbItem } from '@/components/NeBreadcrumbs.vue'

const { t } = useI18n()

const filters = useTrafficFilter()
type FilterableBreadcrumbItem = BreadcrumbItem & {
key: string
}

const { loading, error, data, loadData } = useTrafficStats()
const themeStore = useThemeStore()
const { get, list, remove, misses, contains } = useTrafficFilter()
const { data, error, loading, loadData } = useTrafficStats()

watchEffect(() => {
if (!filters.active.value) {
loadData()
loadData(get('client'), get('app'), get('protocol'), get('host'))
})

const { t } = useI18n()

const filtersToBreadcrumb = computed<FilterableBreadcrumbItem[]>(() => {
let order = 1
// add a default item to the breadcrumb
const defaultItem: FilterableBreadcrumbItem = {
key: 'default',
order: order++,
label: t('standalone.real_time_monitor.traffic')
}
return list.value
.map((filter) => {
let label = ''
switch (filter.key) {
case 'app':
if (filter.value.startsWith('netify.')) {
label = filter.value.slice(7)
} else {
label = filter.value
}
if (label == 'unknown') {
label = t('common.unknown')
} else {
label = label.charAt(0).toUpperCase() + label.slice(1)
}
break
case 'client':
label = filter.value
break
case 'host':
label = filter.value
break
case 'protocol':
label = filter.value.toUpperCase()
break
default:
label = t(`standalone.real_time_monitor.${filter.key}`)
}
return {
key: filter.key as string,
order: order++,
label: label
}
})
.concat(defaultItem)
})

function handleBreadcrumbClick(item: BreadcrumbItem) {
remove(
filtersToBreadcrumb.value
.filter((breadcrumbItem) => breadcrumbItem.order > item.order)
.map((breadcrumbItem) => breadcrumbItem.key) as AvailableFilters[]
)
}

const resolvedHostname = computed(
(): string | undefined =>
data.value.clients.find((client) => client.id == get('client'))?.label ?? undefined
)

const applicationName = computed(
(): string | undefined =>
data.value.applications?.find((app) => app.id == get('app'))?.label ?? undefined
)

const hoursLabels = computed(() => {
return data.value.hourly_traffic.map((value) => value.id)
})
Expand All @@ -57,8 +121,12 @@ const hoursDatasets = computed(() => {
</script>

<template>
<FilteredTraffic v-if="filters.active" />
<div v-else class="space-y-12">
<div class="space-y-6">
<NeBreadcrumbs
v-if="filtersToBreadcrumb.length > 1"
:items="filtersToBreadcrumb"
@click="handleBreadcrumbClick"
/>
<NeSkeleton v-if="loading" :lines="10" />
<NeInlineNotification
v-else-if="error"
Expand All @@ -67,55 +135,72 @@ const hoursDatasets = computed(() => {
kind="error"
/>
<template v-else>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-12">
<NeCard
:title="t('standalone.real_time_monitor.daily_total_traffic')"
class="sm:col-span-6 md:col-span-6 lg:col-span-4 xl:col-span-3 2xl:col-span-3"
>
<SimpleStat>
<span v-if="data?.total_traffic != 0">
{{ byteFormat1024(data?.total_traffic) }}
</span>
<span v-else> N/A </span>
</SimpleStat>
</NeCard>
<NeCard
:title="t('standalone.real_time_monitor.recent_traffic')"
class="row-span-2 sm:col-span-12 xl:col-span-9 2xl:col-span-9"
>
<div class="flex flex-col gap-6 xl:flex-row">
<div class="flex flex-col gap-6 sm:w-96">
<NeCard :title="t('standalone.real_time_monitor.daily_total_traffic')">
<SimpleStat>
<span v-if="data.total_traffic != 0">{{ byteFormat1024(data.total_traffic) }}</span>
<span v-else> N/A </span>
</SimpleStat>
</NeCard>
<NeCard v-if="contains('client')" :title="t('standalone.dashboard.hostname')">
<SimpleStat>
<p v-if="resolvedHostname != get('client')">{{ resolvedHostname }}</p>
<p class="[&:nth-child(2)]:text-lg">{{ get('client') }}</p>
</SimpleStat>
</NeCard>
<NeCard v-if="applicationName" :title="t('standalone.real_time_monitor.application')">
<SimpleStat> {{ applicationName }}</SimpleStat>
</NeCard>
<NeCard v-if="contains('protocol')" :title="t('standalone.real_time_monitor.protocol')">
<SimpleStat> {{ get('protocol').toUpperCase() }}</SimpleStat>
</NeCard>
<NeCard v-if="contains('host')" :title="t('standalone.real_time_monitor.remote_hosts')">
<SimpleStat> {{ get('host') }}</SimpleStat>
</NeCard>
</div>
<NeCard :title="t('standalone.real_time_monitor.recent_traffic')" class="flex-1 self-start">
<TrafficByHourChart
v-if="data?.hourly_traffic.length ?? 0 > 0"
v-if="data.hourly_traffic.length > 0"
:datasets="hoursDatasets"
:labels="hoursLabels"
height="25vh"
/>
<NeEmptyState
v-else
:title="t('standalone.real_time_monitor.no_data_available')"
:icon="faEmptySet"
:title="t('standalone.real_time_monitor.no_data_available')"
/>
</NeCard>
</div>
<div class="grid grid-cols-1 gap-6 xl:grid-cols-2">
<div class="grid gap-6 xl:grid-cols-2">
<TrafficCard
v-if="misses('client')"
:data="data.clients"
:title="t('standalone.real_time_monitor.local_hosts')"
:data="data?.clients ?? []"
filterable
filterableKey="client"
filterable-key="client"
/>
<TrafficCard
v-if="misses('app')"
:data="data.applications"
:title="t('standalone.real_time_monitor.applications')"
:data="data?.applications ?? []"
filterable
filterable-key="app"
/>
<TrafficCard
v-if="misses('host')"
:data="data.remote_hosts"
:title="t('standalone.real_time_monitor.remote_hosts')"
:data="data?.remote_hosts ?? []"
filterable
filterable-key="host"
/>
<TrafficCard
v-if="misses('protocol')"
:data="data.protocols"
:title="t('standalone.real_time_monitor.protocols')"
:data="data?.protocols ?? []"
filterable
filterable-key="protocol"
/>
</div>
</template>
Expand Down
Loading

0 comments on commit 586c8c5

Please sign in to comment.