style: format tmpl with prettier

This commit is contained in:
Tine 2024-02-29 12:15:15 +01:00
parent 65db9b3f72
commit 7c8e130845
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
15 changed files with 791 additions and 580 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@ dist/
# NPM # NPM
package-lock.json package-lock.json
package.json package.json
node_modules/
# Database # Database
zdravko.db zdravko.db

3
.prettierrc Normal file
View file

@ -0,0 +1,3 @@
{
"plugins": ["prettier-plugin-go-template"]
}

View file

@ -48,8 +48,14 @@ primary_region = 'waw'
port = 7233 port = 7233
handlers = ['tls'] handlers = ['tls']
[[vm]]
cpu_kind = 'shared'
cpus = 2
memory_mb = 512
processes = ['server']
[[vm]] [[vm]]
cpu_kind = 'shared' cpu_kind = 'shared'
cpus = 1 cpus = 1
memory_mb = 256 memory_mb = 256
processes = ['server', 'worker'] processes = ['worker']

View file

@ -6,14 +6,15 @@
{{ $path = .NavbarActive.Path }} {{ $path = .NavbarActive.Path }}
{{ end }} {{ end }}
<!DOCTYPE html>
<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Zdravko - {{ $title }}</title> <title>Zdravko - {{ $title }}</title>
<link rel="stylesheet" href="/static/css/tailwind.css"> <link rel="stylesheet" href="/static/css/tailwind.css" />
</head> </head>
<body class="bg-gray-100"> <body class="bg-gray-100">
<nav class="navbar"> <nav class="navbar">
@ -22,7 +23,8 @@
{{ $active := eq .Path $path }} {{ $active := eq .Path $path }}
{{ if $active }}aria-current="true"{{ end }} {{ if $active }}aria-current="true"{{ end }}
href="{{ .Path }}" href="{{ .Path }}"
class="{{if $active}}active{{end}}"> class="{{ if $active }}active{{ end }}"
>
{{ .Title }} {{ .Title }}
</a> </a>
{{ end }} {{ end }}
@ -30,8 +32,14 @@
{{ template "main" . }} {{ template "main" . }}
<div class="container mx-auto"> <div class="container mx-auto">
<footer class="text-center text-gray-500 text-xs mt-8 mb-4"> <footer class="text-center text-gray-500 text-xs mt-8 mb-4">
&copy; 2024 Zdravko - <a class="hover:underline" href="https://github.com/mentos1386/zdravko">Open Source</a> &copy; 2024 Zdravko -
<a
class="hover:underline"
href="https://github.com/mentos1386/zdravko"
>Open Source</a
>
</footer> </footer>
</div>
<script src="/static/js/htmx.min.js"></script> <script src="/static/js/htmx.min.js"></script>
</body> </body>
</html> </html>

View file

@ -6,7 +6,10 @@
{{ $path = .SettingsSidebarActive.Path }} {{ $path = .SettingsSidebarActive.Path }}
{{ end }} {{ end }}
<div class="container max-w-screen-lg mt-8 lg:mt-20 grid grid-cols-1 lg:grid-cols-[min-content_minmax(0,1fr)] gap-8">
<div
class="container max-w-screen-lg mt-8 lg:mt-20 grid grid-cols-1 lg:grid-cols-[min-content_minmax(0,1fr)] gap-8"
>
<ul class="sidebar"> <ul class="sidebar">
{{ range .SettingsSidebar }} {{ range .SettingsSidebar }}
<li> <li>
@ -14,20 +17,32 @@
{{ $active := eq .Path $path }} {{ $active := eq .Path $path }}
{{ if $active }}aria-current="true"{{ end }} {{ if $active }}aria-current="true"{{ end }}
href="{{ .Path }}" href="{{ .Path }}"
class="{{if $active}}active{{end}}"> class="{{ if $active }}active{{ end }}"
>
{{ .Title }} {{ .Title }}
</a> </a>
</li> </li>
{{ end }} {{ end }}
</ul> </ul>
<div class="settings"> <div class="settings">
<nav aria-label="Breadcrumb" class="mx-8 lg:mx-0 grid justify-center lg:justify-start"> <nav
aria-label="Breadcrumb"
class="mx-8 lg:mx-0 grid justify-center lg:justify-start"
>
<ol class="inline-flex items-center"> <ol class="inline-flex items-center">
{{ range .SettingsBreadcrumbs }} {{ range .SettingsBreadcrumbs }}
<li class="inline-flex items-center"> <li class="inline-flex items-center">
<a href="{{ .Path }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600"> <a
href="{{ .Path }}"
class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600"
>
{{ .Breadcrumb }} {{ .Breadcrumb }}
<svg aria-hidden="true" class="feather h-4 w-4 mx-1 text-gray-400 overflow-visible"><use href="/static/icons/feather-sprite.svg#chevron-right"/></svg> <svg
aria-hidden="true"
class="feather h-4 w-4 mx-1 text-gray-400 overflow-visible"
>
<use href="/static/icons/feather-sprite.svg#chevron-right" />
</svg>
</a> </a>
</li> </li>
{{ end }} {{ end }}

View file

@ -1,7 +1,15 @@
{{ define "main" }} {{ define "main" }}
<div class="text-center mt-20"> <div class="text-center mt-20">
<h1 class="text-3xl mb-4 font-bold"><span class="text-red-600">Error 404:</span> Page was not found!</h1> <h1 class="text-3xl mb-4 font-bold">
<p>We didn't find the page you were looking for. Please check the URL and try again.</p> <span class="text-red-600">Error 404:</span> Page was not found!
<p>Or you can go back to the <a class="underline text-blue-600" href="/">homepage</a>.</p> </h1>
<p>
We didn't find the page you were looking for. Please check the URL and try
again.
</p>
<p>
Or you can go back to the
<a class="underline text-blue-600" href="/">homepage</a>.
</p>
</div> </div>
{{ end }} {{ end }}

View file

@ -2,11 +2,16 @@
<div class="container max-w-screen-md flex flex-col mt-20"> <div class="container max-w-screen-md flex flex-col mt-20">
<section> <section>
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16"> <div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"> <h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no Incidents, yet. There are no Incidents, yet.
</h1> </h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"> <p
Incidents will allow you to inform your users or co-worker groups about outages and issues. class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
Incidents will allow you to inform your users or co-worker groups
about outages and issues.
</p> </p>
</div> </div>
</section> </section>

View file

@ -16,7 +16,9 @@
{{ end }} {{ end }}
{{ define "hourly" }} {{ define "hourly" }}
<div class="justify-self-end text-sm">{{ .HistoryHourly.Uptime }}% uptime</div> <div class="justify-self-end text-sm">
{{ .HistoryHourly.Uptime }}% uptime
</div>
<div class="grid gap-px col-span-2 grid-flow-col h-8 rounded overflow-hidden"> <div class="grid gap-px col-span-2 grid-flow-col h-8 rounded overflow-hidden">
{{ range .HistoryHourly.History }} {{ range .HistoryHourly.History }}
{{ if eq . "SUCCESS" }} {{ if eq . "SUCCESS" }}
@ -37,16 +39,28 @@
{{ if eq .MonitorsLength 0 }} {{ if eq .MonitorsLength 0 }}
<section> <section>
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16"> <div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"> <h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no monitors yet. There are no monitors yet.
</h1> </h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"> <p
Create a monitor to monitor your services and get notified when they are down. class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
Create a monitor to monitor your services and get notified when they
are down.
</p> </p>
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"> <div
<a href="/settings/monitors/create" class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"> class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"
>
<a
href="/settings/monitors/create"
class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create First Monitor Create First Monitor
<svg class="feather ml-1 h-5 w-5 overflow-visible"><use href="/static/icons/feather-sprite.svg#plus" /></svg> <svg class="feather ml-1 h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a> </a>
</div> </div>
</div> </div>
@ -54,30 +68,59 @@
{{ else }} {{ else }}
{{ if or (eq .Status "UNKNOWN") (eq .Status "SUCCESS") }} {{ if or (eq .Status "UNKNOWN") (eq .Status "SUCCESS") }}
<div class="flex flex-col items-center"> <div class="flex flex-col items-center">
<svg class="feather h-20 w-20 rounded-full bg-green-300 p-4 overflow-visible"><use href="/static/icons/feather-sprite.svg#check" /></svg> <svg
class="feather h-20 w-20 rounded-full bg-green-300 p-4 overflow-visible"
>
<use href="/static/icons/feather-sprite.svg#check" />
</svg>
<h1 class="text-slate-500 mt-4">All services are online</h1> <h1 class="text-slate-500 mt-4">All services are online</h1>
<p class="text-slate-500 text-sm">Last updated on Feb 10 at 10:55am UTC</p> <p class="text-slate-500 text-sm">
Last updated on Feb 10 at 10:55am UTC
</p>
</div> </div>
{{ else }} {{ else }}
<div class="flex flex-col items-center"> <div class="flex flex-col items-center">
<svg class="feather h-20 w-20 rounded-full bg-red-300 p-4 overflow-visible"><use href="/static/icons/feather-sprite.svg#alert-triangle" /></svg> <svg
class="feather h-20 w-20 rounded-full bg-red-300 p-4 overflow-visible"
>
<use href="/static/icons/feather-sprite.svg#alert-triangle" />
</svg>
<h3 class="text-slate-500 mt-4">Degraded performance</h3> <h3 class="text-slate-500 mt-4">Degraded performance</h3>
<p class="text-slate-500 text-sm">Last updated on Feb 10 at 10:55am UTC</p> <p class="text-slate-500 text-sm">
Last updated on Feb 10 at 10:55am UTC
</p>
</div> </div>
{{ end }} {{ end }}
<div class="monitors"> <div class="monitors">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<p class="text-l font-normal text-gray-800 text-center sm:text-left">Monitors</p> <p class="text-l font-normal text-gray-800 text-center sm:text-left">
<div class="inline-flex rounded-md shadow-sm justify-self-center sm:justify-self-end time-range" role="group"> Monitors
<a href="/?time-range=90days" class="{{ if eq .TimeRange "90days" }}active{{end}}" type="button">90 Days</a> </p>
<a href="/?time-range=48hours" class="{{ if eq .TimeRange "48hours" }}active{{end}}" type="button">48 Hours</a> <div
class="inline-flex rounded-md shadow-sm justify-self-center sm:justify-self-end time-range"
role="group"
>
<a
href="/?time-range=90days"
class="{{ if eq .TimeRange "90days" }}active{{ end }}"
type="button"
>90 Days</a
>
<a
href="/?time-range=48hours"
class="{{ if eq .TimeRange "48hours" }}active{{ end }}"
type="button"
>48 Hours</a
>
</div> </div>
</div> </div>
{{ range .HealthChecks }} {{ range .HealthChecks }}
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<div class="flex items-center"> <div class="flex items-center">
{{ if eq .Status "SUCCESS" }} {{ if eq .Status "SUCCESS" }}
<span class="flex w-3 h-3 me-2 bg-green-400 rounded-full"></span> <span
class="flex w-3 h-3 me-2 bg-green-400 rounded-full"
></span>
{{ else if eq .Status "FAILURE" }} {{ else if eq .Status "FAILURE" }}
<span class="flex w-3 h-3 me-2 bg-red-400 rounded-full"></span> <span class="flex w-3 h-3 me-2 bg-red-400 rounded-full"></span>
{{ else }} {{ else }}

View file

@ -1,19 +1,29 @@
{{ define "settings" }} {{ define "settings" }}
{{ $description := "Monitors are constantly checking weather a service is online and working correctly." }} {{ $description := "Monitors are constantly checking weather a service is online and working correctly." }}
{{ if eq .MonitorsLength 0 }} {{ if eq .MonitorsLength 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16"> <div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"> <h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no monitors yet. There are no monitors yet.
</h1> </h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"> <p
class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
{{ $description }} {{ $description }}
</p> </p>
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"> <div
<a href="/settings/monitors/create" class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"> class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"
>
<a
href="/settings/monitors/create"
class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create First Monitor Create First Monitor
<svg class="feather ml-1 h-5 w-5 overflow-visible"><use href="/static/icons/feather-sprite.svg#plus" /></svg> <svg class="feather ml-1 h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a> </a>
</div> </div>
</div> </div>
@ -26,29 +36,24 @@
<p> <p>
{{ $description }} {{ $description }}
</p> </p>
<a href="/settings/monitors/create" class="inline-flex justify-center items-center py-1 px-2 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"> <a
href="/settings/monitors/create"
class="inline-flex justify-center items-center py-1 px-2 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create New Create New
<svg class="feather h-5 w-5 overflow-visible"><use href="/static/icons/feather-sprite.svg#plus" /></svg> <svg class="feather h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a> </a>
</div> </div>
</caption> </caption>
<thead class="text-xs text-gray-700 uppercase bg-gray-50"> <thead class="text-xs text-gray-700 uppercase bg-gray-50">
<tr> <tr>
<th scope="col"> <th scope="col">Name</th>
Name <th scope="col">Worker Groups</th>
</th> <th scope="col">Status</th>
<th scope="col"> <th scope="col">Schedule</th>
Worker Groups <th scope="col">Action</th>
</th>
<th scope="col">
Status
</th>
<th scope="col">
Schedule
</th>
<th scope="col">
Action
</th>
</tr> </tr>
</thead> </thead>
{{ range .Monitors }} {{ range .Monitors }}
@ -59,22 +64,30 @@
</th> </th>
<td> <td>
{{ range .WorkerGroups }} {{ range .WorkerGroups }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"
>
{{ . }} {{ . }}
</span> </span>
{{ end }} {{ end }}
</td> </td>
<td> <td>
{{ if eq .Status "ACTIVE" }} {{ if eq .Status "ACTIVE" }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
ACTIVE ACTIVE
</span> </span>
{{ else if eq .Status "PAUSED" }} {{ else if eq .Status "PAUSED" }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"
>
PAUSED PAUSED
</span> </span>
{{ else }} {{ else }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>
UNKNOWN UNKNOWN
</span> </span>
{{ end }} {{ end }}
@ -83,7 +96,9 @@
{{ .Schedule }} {{ .Schedule }}
</td> </td>
<td> <td>
<a href="/settings/monitors/{{.Slug}}" class="link">Details</a> <a href="/settings/monitors/{{ .Slug }}" class="link"
>Details</a
>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -2,36 +2,57 @@
<section class="p-5"> <section class="p-5">
<form action="/settings/monitors/create" method="post"> <form action="/settings/monitors/create" method="post">
<label for="name">Name</label> <label for="name">Name</label>
<input type="name" name="name" id="name" placeholder="Github.com"> <input type="name" name="name" id="name" placeholder="Github.com" />
<p>Name of the monitor can be anything.</p> <p>Name of the monitor can be anything.</p>
<label for="workergroups">Worker Groups</label> <label for="workergroups">Worker Groups</label>
<input type="text" name="workergroups" id="workergroups" placeholder="NA EU"/> <input
<p>Worker groups are used to distribute the monitor to specific workers.</p> type="text"
<label for="schedule">Schedule</label> name="workergroups"
<input type="text" name="schedule" id="schedule" placeholder="@every 1m" value="@every 1m"/> id="workergroups"
placeholder="NA EU"
/>
<p> <p>
Schedule is a cron expression that defines when the monitor should be executed. Worker groups are used to distribute the monitor to specific workers.
</br> </p>
You can also use <code>@every [interval]</code> where interval is a duration like 5m, 1h, 60s. <label for="schedule">Schedule</label>
Or use <code>@hourly</code>, <code>@daily</code>, <code>@weekly</code>, <code>@monthly</code>, <code>@yearly</code>. <input
type="text"
name="schedule"
id="schedule"
placeholder="@every 1m"
value="@every 1m"
/>
<p>
Schedule is a cron expression that defines when the monitor should be
executed.
<br />
You can also use <code>@every [interval]</code> where interval is a
duration like 5m, 1h, 60s. Or use <code>@hourly</code>,
<code>@daily</code>, <code>@weekly</code>, <code>@monthly</code>,
<code>@yearly</code>.
</p> </p>
<label for="script">Script</label> <label for="script">Script</label>
<input required type="hidden" id="script" name="script"> <input required type="hidden" id="script" name="script" />
<div id="editor" class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"></div> <div
id="editor"
class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
></div>
<p> <p>
Script is what determines the status of a service. Script is what determines the status of a service. You can read more
You can read more about it on <a target="_blank" href="https://k6.io/docs/using-k6/http-requests/">k6 documentation</a>. about it on
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
>k6 documentation</a
>.
</p> </p>
<button type="submit" onclick="save()">Create</button> <button type="submit" onclick="save()">Create</button>
</form> </form>
</section> </section>
<script src="/static/monaco/vs/loader.js"></script> <script src="/static/monaco/vs/loader.js"></script>
<script> <script>
function save() { function save() {
const script = window.editor.getValue(); const script = window.editor.getValue();
document.getElementById('script').value = script; document.getElementById("script").value = script;
} }
script = `import http from 'k6/http'; script = `import http from 'k6/http';
@ -46,20 +67,20 @@ export const options = {
export default function () { export default function () {
http.get('https://example.com'); http.get('https://example.com');
} }
` `;
require.config({ paths: { vs: '/static/monaco/vs' } }); require.config({ paths: { vs: "/static/monaco/vs" } });
require(['vs/editor/editor.main'], function () { require(["vs/editor/editor.main"], function () {
window.editor = monaco.editor.create(document.getElementById('editor'), { window.editor = monaco.editor.create(document.getElementById("editor"), {
value: script, value: script,
language: 'javascript', language: "javascript",
minimap: { enabled: false }, minimap: { enabled: false },
codeLens: false, codeLens: false,
contextmenu: false, contextmenu: false,
}); });
const divElem = document.getElementById('editor'); const divElem = document.getElementById("editor");
const resizeObserver = new ResizeObserver(entries => { const resizeObserver = new ResizeObserver((entries) => {
window.editor.layout(); window.editor.layout();
}); });
resizeObserver.observe(divElem); resizeObserver.observe(divElem);

View file

@ -1,26 +1,45 @@
{{ define "settings" }} {{ define "settings" }}
<section class="p-5"> <section class="p-5">
<form action="/settings/monitors/{{ .Monitor.Slug }}" method="post"> <form action="/settings/monitors/{{ .Monitor.Slug }}" method="post">
<h2> <h2>Configuration</h2>
Configuration
</h2>
<label for="workergroups">Worker Groups</label> <label for="workergroups">Worker Groups</label>
<input type="text" name="workergroups" id="workergroups" value="{{ range .Monitor.WorkerGroups }}{{.}} {{end}}"/> <input
<p>Worker groups are used to distribute the monitor to specific workers.</p> type="text"
<label for="schedule">Schedule</label> name="workergroups"
<input type="text" name="schedule" id="schedule" value="{{ .Monitor.Schedule }}"/> id="workergroups"
value="{{ range .Monitor.WorkerGroups }}{{ . }}{{ end }}"
/>
<p> <p>
Schedule is a cron expression that defines when the monitor should be executed. Worker groups are used to distribute the monitor to specific workers.
</br> </p>
You can also use <code>@every [interval]</code> where interval is a duration like 5m, 1h, 60s. <label for="schedule">Schedule</label>
Or use <code>@hourly</code>, <code>@daily</code>, <code>@weekly</code>, <code>@monthly</code>, <code>@yearly</code>. <input
type="text"
name="schedule"
id="schedule"
value="{{ .Monitor.Schedule }}"
/>
<p>
Schedule is a cron expression that defines when the monitor should be
executed.
<br />
You can also use <code>@every [interval]</code> where interval is a
duration like 5m, 1h, 60s. Or use <code>@hourly</code>,
<code>@daily</code>, <code>@weekly</code>, <code>@monthly</code>,
<code>@yearly</code>.
</p> </p>
<label for="script">Script</label> <label for="script">Script</label>
<input required type="hidden" id="script" name="script"> <input required type="hidden" id="script" name="script" />
<div id="editor" class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"></div> <div
id="editor"
class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
></div>
<p> <p>
Script is what determines the status of a service. Script is what determines the status of a service. You can read more
You can read more about it on <a target="_blank" href="https://k6.io/docs/using-k6/http-requests/">k6 documentation</a>. about it on
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
>k6 documentation</a
>.
</p> </p>
<button type="submit" onclick="save()">Save</button> <button type="submit" onclick="save()">Save</button>
</form> </form>
@ -31,33 +50,46 @@
<h2 class="mb-2 flex flex-row gap-2"> <h2 class="mb-2 flex flex-row gap-2">
Status Status
{{ if eq .Monitor.Status "ACTIVE" }} {{ if eq .Monitor.Status "ACTIVE" }}
<span class="self-center h-fit w-fit px-2 text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"> <span
class="self-center h-fit w-fit px-2 text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
ACTIVE ACTIVE
</span> </span>
{{ else if eq .Monitor.Status "PAUSED" }} {{ else if eq .Monitor.Status "PAUSED" }}
<span class="self-center h-fit w-fit px-2 text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"> <span
class="self-center h-fit w-fit px-2 text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800"
>
PAUSED PAUSED
</span> </span>
{{ end }} {{ end }}
</h2> </h2>
<p class="text-sm mb-2"> <p class="text-sm mb-2">
Pausing the monitor will stop it from executing. Pausing the monitor will stop it from executing. This can be useful in
This can be useful in cases of expected downtime. cases of expected downtime. Or when the monitor is not needed anymore.
Or when the monitor is not needed anymore.
</p> </p>
{{ if eq .Monitor.Status "ACTIVE" }} {{ if eq .Monitor.Status "ACTIVE" }}
<a class="block text-center py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100" href="/settings/monitors/{{ .Monitor.Slug }}/disable">Pause</a> <a
class="block text-center py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100"
href="/settings/monitors/{{ .Monitor.Slug }}/disable"
>Pause</a
>
{{ else if eq .Monitor.Status "PAUSED" }} {{ else if eq .Monitor.Status "PAUSED" }}
<a class="block text-center py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100" href="/settings/monitors/{{ .Monitor.Slug }}/enable">Resume</a> <a
class="block text-center py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100"
href="/settings/monitors/{{ .Monitor.Slug }}/enable"
>Resume</a
>
{{ end }} {{ end }}
</section> </section>
<section class="p-2 flex-1 border-4 border-red-300"> <section class="p-2 flex-1 border-4 border-red-300">
<h2 class="mb-2"> <h2 class="mb-2">Danger Zone</h2>
Danger Zone
</h2>
<p class="text-sm mb-2">Permanently delete this monitor.</p> <p class="text-sm mb-2">Permanently delete this monitor.</p>
<a class="block text-center focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2" href="/settings/monitors/{{ .Monitor.Slug }}/delete">Delete</a> <a
class="block text-center focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2"
href="/settings/monitors/{{ .Monitor.Slug }}/delete"
>Delete</a
>
</section> </section>
</div> </div>
@ -65,9 +97,7 @@
<table> <table>
<caption> <caption>
History History
<p> <p>Last 10 executions of monitor script.</p>
Last 10 executions of monitor script.
</p>
</caption> </caption>
<thead> <thead>
<tr> <tr>
@ -81,16 +111,20 @@
{{ range .History }} {{ range .History }}
<tr> <tr>
<td> <td>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{if eq .Status "SUCCESS"}}bg-green-100 text-green-800{{else}}bg-red-100 text-red-800{{end}}"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ if eq .Status "SUCCESS" }}
bg-green-100 text-green-800
{{ else }}
bg-red-100 text-red-800
{{ end }}"
>
{{ .Status }} {{ .Status }}
</span> </span>
</td> </td>
<td> <td>
{{ .CreatedAt.Format "2006-01-02 15:04:05" }} {{ .CreatedAt.Format "2006-01-02 15:04:05" }}
</td> </td>
<td> <td>{ .Duration }</td>
{ .Duration }
</td>
<td class="whitespace-normal"> <td class="whitespace-normal">
{{ .Note }} {{ .Note }}
</td> </td>

View file

@ -1,24 +1,37 @@
{{ define "settings" }} {{ define "settings" }}
<div class="pt-8 mx-auto max-w-screen-xl text-center lg:pt-16"> <div class="pt-8 mx-auto max-w-screen-xl text-center lg:pt-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"> <h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
Hi there, {{ .User.Email }}. Hi there, {{ .User.Email }}.
</h1> </h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 md:px-40"> <p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 md:px-40">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
</p> </p>
</div> </div>
<div class="mx-auto max-w-screen-xl flex flex-col sm:flex-row gap-4"> <div class="mx-auto max-w-screen-xl flex flex-col sm:flex-row gap-4">
<div class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"> <div
class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"
>
<h3 class="text-sm leading-6 font-medium text-gray-400">Total Workers</h3> <h3 class="text-sm leading-6 font-medium text-gray-400">Total Workers</h3>
<p class="text-3xl font-bold text-black">42</p> <p class="text-3xl font-bold text-black">42</p>
</div> </div>
<div class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"> <div
<h3 class="text-sm leading-6 font-medium text-gray-400">Total Monitors</h3> class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"
>
<h3 class="text-sm leading-6 font-medium text-gray-400">
Total Monitors
</h3>
<p class="text-3xl font-bold text-black">42</p> <p class="text-3xl font-bold text-black">42</p>
</div> </div>
<div class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"> <div
<h3 class="text-sm leading-6 font-medium text-gray-400">Total Notifications</h3> class="inline-block bg-white rounded-lg shadow p-5 text-center sm:mt-0 sm:ml-2 sm:text-left"
>
<h3 class="text-sm leading-6 font-medium text-gray-400">
Total Notifications
</h3>
<p class="text-3xl font-bold text-black">42</p> <p class="text-3xl font-bold text-black">42</p>
</div> </div>
</div> </div>

View file

@ -1,19 +1,29 @@
{{ define "settings" }} {{ define "settings" }}
{{ $description := "Worker Groups are used to match multiple workers together. They can be used to difirentiate between regions, environments, networks etc." }} {{ $description := "Worker Groups are used to match multiple workers together. They can be used to difirentiate between regions, environments, networks etc." }}
{{ if eq .WorkerGroupsLength 0 }} {{ if eq .WorkerGroupsLength 0 }}
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16"> <div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16">
<h1 class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"> <h1
class="mb-4 text-2xl font-extrabold tracking-tight leading-none text-gray-900 md:text-3xl lg:text-4xl"
>
There are no worker groups yet. There are no worker groups yet.
</h1> </h1>
<p class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"> <p
class="mb-8 text-l font-normal text-gray-500 lg:text-l sm:px-8 lg:px-40"
>
{{ $description }} {{ $description }}
</p> </p>
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"> <div
<a href="/settings/worker-groups/create" class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"> class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0"
>
<a
href="/settings/worker-groups/create"
class="inline-flex justify-center items-center py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create First Worker Group Create First Worker Group
<svg class="feather ml-1 h-5 w-5 overflow-visible"><use href="/static/icons/feather-sprite.svg#plus" /></svg> <svg class="feather ml-1 h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a> </a>
</div> </div>
</div> </div>
@ -26,26 +36,23 @@
<p> <p>
{{ $description }} {{ $description }}
</p> </p>
<a href="/settings/worker-groups/create" class="inline-flex justify-center items-center py-1 px-2 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"> <a
href="/settings/worker-groups/create"
class="inline-flex justify-center items-center py-1 px-2 text-sm font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300"
>
Create New Create New
<svg class="feather h-5 w-5 overflow-visible"><use href="/static/icons/feather-sprite.svg#plus" /></svg> <svg class="feather h-5 w-5 overflow-visible">
<use href="/static/icons/feather-sprite.svg#plus" />
</svg>
</a> </a>
</div> </div>
</caption> </caption>
<thead> <thead>
<tr> <tr>
<th> <th>Name</th>
Name <th>Workers</th>
</th> <th>Monitors</th>
<th> <th>Action</th>
Workers
</th>
<th>
Monitors
</th>
<th>
Action
</th>
</tr> </tr>
</thead> </thead>
{{ range .WorkerGroups }} {{ range .WorkerGroups }}
@ -56,11 +63,15 @@
</th> </th>
<td> <td>
{{ if eq ( len .ActiveWorkers) 0 }} {{ if eq ( len .ActiveWorkers) 0 }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>
NONE NONE
</span> </span>
{{ else }} {{ else }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
{{ len .ActiveWorkers }} ONLINE {{ len .ActiveWorkers }} ONLINE
</span> </span>
{{ end }} {{ end }}
@ -69,7 +80,9 @@
{{ len .Monitors }} {{ len .Monitors }}
</td> </td>
<td> <td>
<a href="/settings/worker-groups/{{.Slug}}" class="link">Details</a> <a href="/settings/worker-groups/{{ .Slug }}" class="link"
>Details</a
>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -1,7 +1,9 @@
{{ define "settings" }} {{ define "settings" }}
<section class="p-5"> <section class="p-5">
<form action="/settings/worker-groups/create" method="post"> <form action="/settings/worker-groups/create" method="post">
<label for="name" class="block mb-2 text-sm font-medium text-gray-900">Name</label> <label for="name" class="block mb-2 text-sm font-medium text-gray-900"
>Name</label
>
<input type="text" name="name" id="name" placeholder="aws-eu-central-1" /> <input type="text" name="name" id="name" placeholder="aws-eu-central-1" />
<p>Worker group name can be anything.</p> <p>Worker group name can be anything.</p>
<button type="submit">Create</button> <button type="submit">Create</button>

View file

@ -2,14 +2,27 @@
<section class="p-5"> <section class="p-5">
<h2> <h2>
Token Token
<span>Use it as <code>WORKER_GROUP_TOKEN</code> configuration option.</span> <span
>Use it as <code>WORKER_GROUP_TOKEN</code> configuration option.</span
>
</h2> </h2>
<div class="grid grid-cols-[auto_min-content] gap-2"> <div class="grid grid-cols-[auto_min-content] gap-2">
<pre id="token" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg block w-full p-2.5 overflow-x-auto">{{ .Worker.Token }}</pre> <pre
<button id="copy-token" data-copy-to-clipboard-target="npm-install" class="col-span-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto p-2.5 text-center items-center inline-flex justify-center"> id="token"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg block w-full p-2.5 overflow-x-auto"
>
{{ .Worker.Token }}</pre
>
<button
id="copy-token"
data-copy-to-clipboard-target="npm-install"
class="col-span-1 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto p-2.5 text-center items-center inline-flex justify-center"
>
<span id="default-message">Copy</span> <span id="default-message">Copy</span>
<span id="success-message" class="hidden inline-flex items-center"> <span id="success-message" class="hidden inline-flex items-center">
<svg class="feather h-4 w-4 mr-1 overflow-visible"><use href="/static/icons/feather-sprite.svg#check"/></svg> <svg class="feather h-4 w-4 mr-1 overflow-visible">
<use href="/static/icons/feather-sprite.svg#check" />
</svg>
Copied! Copied!
</span> </span>
</button> </button>
@ -23,21 +36,27 @@
<span> <span>
Active Workers Active Workers
{{ if eq ( len .Worker.ActiveWorkers) 0 }} {{ if eq ( len .Worker.ActiveWorkers) 0 }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>
NONE NONE
</span> </span>
{{ else }} {{ else }}
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"> <span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>
{{ len .Worker.ActiveWorkers }} ONLINE {{ len .Worker.ActiveWorkers }} ONLINE
</span> </span>
{{ end }} {{ end }}
</span> </span>
<p> <p>Current workers that were online in last minutes.</p>
Current workers that were online in last minutes.
</p>
</caption> </caption>
{{ if eq ( len .Worker.ActiveWorkers) 0 }} {{ if eq ( len .Worker.ActiveWorkers) 0 }}
<thead><tr><th>No workers online for this worker group.</th></tr></thead> <thead>
<tr>
<th>No workers online for this worker group.</th>
</tr>
</thead>
{{ else }} {{ else }}
<thead> <thead>
<tr> <tr>
@ -56,28 +75,33 @@
</section> </section>
<section class="p-2 flex-1 border-4 border-red-300"> <section class="p-2 flex-1 border-4 border-red-300">
<h2 class="mb-2"> <h2 class="mb-2">Danger Zone</h2>
Danger Zone <p class="text-sm mb-2">
</h2> Permanently delete this worker group. Workers will not be able to
<p class="text-sm mb-2">Permanently delete this worker group. Workers will not be able to connect anymore.</p> connect anymore.
<a class="block text-center focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2" href="/settings/worker-groups/{{ .Worker.Slug }}/delete">Delete</a> </p>
<a
class="block text-center focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2"
href="/settings/worker-groups/{{ .Worker.Slug }}/delete"
>Delete</a
>
</section> </section>
</div> </div>
<script> <script>
const copyTokenButton = document.getElementById('copy-token'); const copyTokenButton = document.getElementById("copy-token");
copyTokenButton.addEventListener('click', function() { copyTokenButton.addEventListener("click", function () {
this.blur(); this.blur();
const copyText = document.getElementById('token'); const copyText = document.getElementById("token");
navigator.clipboard.writeText(copyText.innerText); navigator.clipboard.writeText(copyText.innerText);
const defaultMessage = document.getElementById('default-message'); const defaultMessage = document.getElementById("default-message");
const successMessage = document.getElementById('success-message'); const successMessage = document.getElementById("success-message");
defaultMessage.classList.add('hidden'); defaultMessage.classList.add("hidden");
successMessage.classList.remove('hidden'); successMessage.classList.remove("hidden");
setTimeout(() => { setTimeout(() => {
defaultMessage.classList.remove('hidden'); defaultMessage.classList.remove("hidden");
successMessage.classList.add('hidden'); successMessage.classList.add("hidden");
}, 1500); }, 1500);
}); });
</script> </script>