-
-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add metrics components to frontend (#246)
Co-authored-by: Sean Connole <sean.connole@dmetrics.com>
- Loading branch information
Showing
8 changed files
with
301 additions
and
21 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,20 @@ | ||
import Chart from 'chart.js/auto' | ||
import 'chartjs-adapter-moment' | ||
|
||
import Alpine from 'alpinejs' | ||
|
||
import Anchor from '@alpinejs/anchor' | ||
import Collapse from '@alpinejs/collapse' | ||
import Focus from '@alpinejs/focus' | ||
import Ui from '@alpinejs/ui' | ||
|
||
Chart.defaults.color = '#fff' | ||
window.Chart = Chart | ||
|
||
Alpine.plugin(Anchor) | ||
Alpine.plugin(Collapse) | ||
Alpine.plugin(Focus) | ||
Alpine.plugin(Ui) | ||
|
||
window.Alpine = Alpine | ||
Alpine.start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
@props([ | ||
'metric', | ||
]) | ||
|
||
@use('\Cachet\Enums\MetricViewEnum') | ||
|
||
<div x-data="chart"> | ||
<div class="flex flex-col gap-2"> | ||
<div class="flex items-center gap-1.5"> | ||
<div class="font-semibold leading-6">{{ $metric->name }}</div> | ||
|
||
<div x-data x-popover class="flex items-center"> | ||
<button x-ref="anchor" x-popover:button> | ||
<x-heroicon-o-question-mark-circle class="size-4 text-zinc-500 dark:text-zinc-300" /> | ||
</button> | ||
<div x-popover:panel x-cloak x-transition.opacity x-anchor.right.offset.8="$refs.anchor" class="rounded bg-white px-2 py-1 text-xs font-medium text-zinc-800 drop-shadow dark:text-zinc-800"> | ||
<span class="pointer-events-none absolute -left-1 top-1.5 size-4 rotate-45 bg-white"></span> | ||
<p class="relative">{{ $metric->description }}</p> | ||
</div> | ||
</div> | ||
|
||
<!-- Period Selector --> | ||
<select x-model="period" class="ml-auto rounded-md border border-gray-300 bg-white text-sm font-medium text-gray-900 dark:border-gray-700 dark:bg-zinc-800 dark:text-gray-100"> | ||
@foreach ([MetricViewEnum::last_hour, MetricViewEnum::today, MetricViewEnum::week, MetricViewEnum::month] as $value) | ||
<option value="{{ $value }}">{{ $value->getLabel() }}</option> | ||
@endforeach | ||
</select> | ||
</div> | ||
<canvas x-ref="canvas" height="380" class="text-gray rounded-md bg-white p-3 shadow-sm ring-1 ring-gray-900/5 dark:bg-zinc-800 dark:text-white dark:ring-gray-100/10"></canvas> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
document.addEventListener('alpine:init', () => { | ||
Alpine.data('chart', () => ({ | ||
metric: {{ Js::from($metric) }}, | ||
period: {{ Js::from($metric->default_view) }}, | ||
points: [[], [], [], []], | ||
chart: null, | ||
init, | ||
})) | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<script> | ||
const now = new Date() | ||
const previousHour = new Date(now - 60 * 60 * 1000) | ||
const previous24Hours = new Date(now - 24 * 60 * 60 * 1000) | ||
const previous7Days = new Date(now - 7 * 24 * 60 * 60 * 1000) | ||
const previous30Days = new Date(now - 30 * 24 * 60 * 60 * 1000) | ||
const MetricView = {{ | ||
Js::from([ | ||
'last_hour' => \Cachet\Enums\MetricViewEnum::last_hour->value, | ||
'today' => \Cachet\Enums\MetricViewEnum::today->value, | ||
'week' => \Cachet\Enums\MetricViewEnum::week->value, | ||
'month' => \Cachet\Enums\MetricViewEnum::month->value, | ||
]) | ||
}} | ||
function getCssVar(name) { | ||
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() | ||
} | ||
function getFontColor() { | ||
if (window.matchMedia('(prefers-color-scheme: dark)').matches === true) { | ||
return `rgba(${getCssVar('--gray-100')}, 1)` | ||
} | ||
return `rgba(${getCssVar('--gray-800')}, 1)` | ||
} | ||
function getThemeColors() { | ||
const fontColor = getFontColor() | ||
const accent = `rgba(${getCssVar('--accent')}, 1)` | ||
const accentBackground = `rgba(${getCssVar('--accent-background')}, 0.2)` | ||
return { | ||
fontColor: fontColor, | ||
backgroundColors: [accent, accentBackground], | ||
borderColor: accent, | ||
} | ||
} | ||
let themeColors = getThemeColors() | ||
function init() { | ||
// Parse metric points | ||
const metricPoints = this.metric.metric_points.map((point) => { | ||
return { | ||
x: new Date(point.x), | ||
y: point.y, | ||
} | ||
}) | ||
// Filter points based on the selected period | ||
this.points[0] = metricPoints.filter((point) => point.x >= previousHour) | ||
this.points[1] = metricPoints.filter((point) => point.x >= previous24Hours) | ||
this.points[2] = metricPoints.filter((point) => point.x >= previous7Days) | ||
this.points[3] = metricPoints.filter((point) => point.x >= previous30Days) | ||
// Initialize chart | ||
const chart = new Chart(this.$refs.canvas, { | ||
type: 'line', | ||
data: { | ||
datasets: [ | ||
{ | ||
label: this.metric.suffix, | ||
data: this.points[this.period], | ||
fill: false, | ||
backgroundColor: themeColors.backgroundColors, | ||
borderColor: themeColors.borderColor, | ||
tension: 0.1, | ||
}, | ||
], | ||
}, | ||
options: { | ||
scales: { | ||
x: { | ||
ticks: { | ||
color: themeColors.fontColor, | ||
}, | ||
type: 'timeseries', | ||
}, | ||
y: { | ||
ticks: { | ||
color: themeColors.fontColor, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
this.$watch('period', () => { | ||
chart.data.datasets[0].data = this.points[this.period] | ||
chart.options.scales.x.time.unit = getTimeUnit(this.period) | ||
chart.update() | ||
}) | ||
function getTimeUnit(period) { | ||
if (period == MetricView.last_hour) return 'minute' | ||
if (period == MetricView.today) return 'hour' | ||
if (period == MetricView.week) return 'week' | ||
if (period == MetricView.month) return 'month' | ||
return 'day' | ||
} | ||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { | ||
themeColors = getThemeColors() | ||
chart.data.datasets[0].backgroundColor = themeColors.backgroundColors | ||
chart.data.datasets[0].borderColor = themeColors.borderColor | ||
chart.options.plugins.legend.labels.color = themeColors.fontColor | ||
chart.options.plugins.tooltip.bodyColor = themeColors.fontColor | ||
chart.options.plugins.tooltip.titleColor = themeColors.fontColor | ||
chart.options.scales.x.ticks.color = themeColors.fontColor | ||
chart.options.scales.y.ticks.color = themeColors.fontColor | ||
chart.update() | ||
}) | ||
} | ||
</script> | ||
|
||
<div class="flex flex-col gap-8"> | ||
@foreach ($metrics as $metric) | ||
<x-cachet::metric :metric="$metric" /> | ||
@endforeach | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.