mirror of
https://github.com/BluemediaDev/fancy-gatus.git
synced 2025-07-01 01:12:42 +02:00
123 lines
3.7 KiB
Svelte
123 lines
3.7 KiB
Svelte
<script lang="ts">
|
|
import axios from 'axios'
|
|
import { onMount } from 'svelte'
|
|
import type { Config } from '$lib/types/config'
|
|
import type { Status } from '$lib/types/api'
|
|
import Loader from '$lib/components/Loader.svelte'
|
|
import Header from '$lib/components/Header.svelte'
|
|
import Notice from '$lib/components/Notice.svelte'
|
|
import OverallStatus from '$lib/components/OverallStatus.svelte'
|
|
import EndpointGroup from '$lib/components/StatusGroup.svelte'
|
|
import RefreshSettings from '$lib/components/RefreshSettings.svelte'
|
|
import Footer from '$lib/components/Footer.svelte'
|
|
|
|
let loading = $state(true)
|
|
let config: Config = $state({})
|
|
let apiData: Status[] = $state([])
|
|
|
|
function getConfig() {
|
|
axios
|
|
.get('config.json', { baseURL: '/' })
|
|
.then((response) => {
|
|
config = response.data
|
|
// Set title if defined in config
|
|
if (config.title) {
|
|
document.title = config.title
|
|
}
|
|
getApiData()
|
|
})
|
|
.catch((error) => {
|
|
if (error.response.status === 404) {
|
|
console.warn('No config.json file found. Using default values.')
|
|
getApiData()
|
|
} else {
|
|
console.log('Error getting config: ' + error)
|
|
}
|
|
})
|
|
}
|
|
|
|
function getApiData() {
|
|
// Set base URL for API calls if defined in config
|
|
if (config.gatusBaseUrl && axios.defaults.baseURL !== config.gatusBaseUrl) {
|
|
axios.defaults.baseURL = config.gatusBaseUrl
|
|
}
|
|
axios
|
|
.get('/api/v1/endpoints/statuses')
|
|
.then((response) => {
|
|
apiData = response.data
|
|
loading = false
|
|
})
|
|
.catch((error) => {
|
|
console.log(error)
|
|
})
|
|
}
|
|
|
|
// Group statuses by their group name
|
|
// and sort them according to the config if specified
|
|
let groups: { title: string; statuses: Status[] }[] = $derived.by(() => {
|
|
// Group statuses by group name
|
|
let groups: Map<string, Status[]> = new Map<string, Status[]>()
|
|
apiData.map((status) => {
|
|
// Filter statuses that should be hidden
|
|
if (config.hiddenStatuses?.includes(status.name)) return
|
|
if (!status.group) {
|
|
status.group = 'Ungrouped'
|
|
}
|
|
// Filter groups that should be hidden
|
|
if (config.hiddenGroups?.includes(status.group)) return
|
|
let groupStatuses = groups.get(status.group) || []
|
|
groupStatuses.push(status)
|
|
groups.set(status.group, groupStatuses)
|
|
})
|
|
|
|
// Sort by config
|
|
let tmp = groups
|
|
let sortedGroups: { title: string; statuses: Status[] }[] = []
|
|
if (config.groupOrder) {
|
|
config.groupOrder.forEach((key) => {
|
|
if (tmp.has(key)) {
|
|
sortedGroups.push({ title: key, statuses: tmp.get(key)! })
|
|
tmp.delete(key)
|
|
}
|
|
})
|
|
}
|
|
|
|
// Sort remaining group alphabetically
|
|
let sortedKeys = [...tmp.keys()].sort((a, b) => a.localeCompare(b))
|
|
sortedKeys.map((key) => {
|
|
let statuses = tmp.get(key)!
|
|
sortedGroups.push({ title: key, statuses })
|
|
})
|
|
return sortedGroups
|
|
})
|
|
|
|
// Array of statuses where the last result has success = false
|
|
let failedStatuses = $derived.by(() => {
|
|
return apiData.filter((status) => {
|
|
return !status.results[status.results.length - 1].success
|
|
})
|
|
})
|
|
|
|
onMount(() => {
|
|
getConfig()
|
|
})
|
|
</script>
|
|
|
|
{#if loading}
|
|
<Loader />
|
|
{:else}
|
|
<Header title={config.title} />
|
|
{#if config.notice}
|
|
<Notice notice={config.notice} />
|
|
{/if}
|
|
<OverallStatus {failedStatuses} />
|
|
{#each groups as group (group.title)}
|
|
<EndpointGroup
|
|
title={group.title}
|
|
statuses={group.statuses}
|
|
expandByDefault={config.defaultExpandGroups}
|
|
/>
|
|
{/each}
|
|
<RefreshSettings defaultRefreshInterval={config.defaultRefreshInterval} onRefresh={getConfig} />
|
|
<Footer />
|
|
{/if}
|