rebrand: fork Gatus as PANDUS with custom UI identity
New indigo/purple shield+pulse logo, theme colors, localStorage key prefixes, manifest metadata. Footer and Social link retain attribution to upstream Gatus repo per Apache 2.0.
This commit is contained in:
parent
ed1107b41a
commit
7c6bc53dc7
@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "gatus",
|
||||
"name": "Gatus",
|
||||
"short_name": "Gatus",
|
||||
"description": "Gatus is an advanced automated status page that lets you monitor your applications and configure alerts to notify you if there's an issue",
|
||||
"id": "pandus",
|
||||
"name": "PANDUS",
|
||||
"short_name": "PANDUS",
|
||||
"description": "PANDUS is a status page and health dashboard for monitoring your applications",
|
||||
"lang": "en",
|
||||
"scope": "/",
|
||||
"start_url": "/",
|
||||
|
||||
@ -23,13 +23,13 @@
|
||||
<img
|
||||
v-if="logo"
|
||||
:src="logo"
|
||||
alt="Gatus"
|
||||
alt="PANDUS"
|
||||
class="w-full h-full object-contain"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
src="./assets/logo.svg"
|
||||
alt="Gatus"
|
||||
alt="PANDUS"
|
||||
class="w-full h-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
@ -100,7 +100,7 @@
|
||||
<div class="container mx-auto px-4 py-6 max-w-7xl">
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="text-sm text-muted-foreground text-center">
|
||||
Powered by <a href="https://gatus.io" target="_blank" class="font-medium text-emerald-800 hover:text-emerald-600">Gatus</a>
|
||||
Powered by <a href="https://github.com/TwiN/gatus" target="_blank" class="font-medium text-indigo-600 hover:text-indigo-400 dark:text-indigo-400 dark:hover:text-indigo-300">Gatus</a>
|
||||
</div>
|
||||
<Social />
|
||||
</div>
|
||||
@ -115,9 +115,9 @@
|
||||
<div v-if="logo" class="flex items-center justify-center gap-4 mb-4">
|
||||
<img :src="logo" alt="" class="w-20 h-20 object-contain" />
|
||||
<div class="w-px h-12 bg-border"></div>
|
||||
<img src="./assets/logo.svg" alt="Gatus" class="w-20 h-20" />
|
||||
<img src="./assets/logo.svg" alt="PANDUS" class="w-20 h-20" />
|
||||
</div>
|
||||
<img v-else src="./assets/logo.svg" alt="Gatus" class="w-20 h-20 mx-auto mb-4" />
|
||||
<img v-else src="./assets/logo.svg" alt="PANDUS" class="w-20 h-20 mx-auto mb-4" />
|
||||
<CardTitle class="text-3xl">{{ header }}</CardTitle>
|
||||
<p class="text-muted-foreground mt-2">{{ loginSubtitle }}</p>
|
||||
</CardHeader>
|
||||
@ -181,7 +181,7 @@ const logo = computed(() => {
|
||||
})
|
||||
|
||||
const header = computed(() => {
|
||||
return window.config && window.config.header && window.config.header !== '{{ .UI.Header }}' ? window.config.header : "Gatus"
|
||||
return window.config && window.config.header && window.config.header !== '{{ .UI.Header }}' ? window.config.header : "PANDUS"
|
||||
})
|
||||
|
||||
const link = computed(() => {
|
||||
@ -193,7 +193,7 @@ const buttons = computed(() => {
|
||||
})
|
||||
|
||||
const loginSubtitle = computed(() => {
|
||||
return window.config && window.config.loginSubtitle && window.config.loginSubtitle !== '{{ .UI.LoginSubtitle }}' ? window.config.loginSubtitle : "System Monitoring Dashboard"
|
||||
return window.config && window.config.loginSubtitle && window.config.loginSubtitle !== '{{ .UI.LoginSubtitle }}' ? window.config.loginSubtitle : "Status Monitoring Dashboard"
|
||||
})
|
||||
|
||||
// Methods
|
||||
|
||||
@ -1 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89.76 89.75"><defs><style>.cls-1{fill:#3cad4b;}.cls-2{fill:#017400;}.cls-3{fill:#1e9025;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M33.67,65.35a23.35,23.35,0,0,1,.08-41,22.94,22.94,0,0,1,3.8-1.64A23,23,0,0,0,53.6,1C53,0,51,0,44.89,0c-9.08,0-9.21.17-8.81,3.22,1.07,8.12-9.42,12.5-14.45,6-1.94-2.52-2.1-2.52-8.68,4.16-6.22,6.3-6.33,6.28-3.77,8.25a8.09,8.09,0,0,1,2.56,9.53A8.15,8.15,0,0,1,3.08,36C0,35.63,0,35.73,0,45.2.08,53.81,0,54,3.3,53.63A8.06,8.06,0,0,1,9.76,67.52c-3,2.83-2.84,2.61,2.84,8.48,5.43,5.62,6.33,6.73,8.16,5.24L34,68A1.63,1.63,0,0,0,33.67,65.35Z"/><path class="cls-2" d="M85.43,36.13a8.11,8.11,0,0,1-5.27-14.21c2.85-2.5,2.82-2.37-3.55-8.75-4.31-4.31-5.71-5.75-6.87-5.4l-14,14a1.65,1.65,0,0,0,.36,2.61,23.35,23.35,0,0,1-.1,41,24.5,24.5,0,0,1-5.11,2c-8.54,2.28-14.73,9.63-14.73,18.47v1.27c.15,2.54,1.19,2.42,8.06,2.52,9.32.14,9.1.35,9.38-4.66a8.11,8.11,0,0,1,14-5.09c3,3.15,2.39,3.11,8.73-3.14,6.56-6.47,6.86-6.25,3.68-9.14a8.1,8.1,0,0,1,6.06-14.07c3.68.27,3.51.06,3.63-8.09C89.85,36.27,90,36.16,85.43,36.13Z"/><path class="cls-3" d="M41.11,59h8a.76.76,0,0,0,.77-.76V50.43a.76.76,0,0,1,.77-.76h7.84a.78.78,0,0,0,.77-.77V40.84a.77.77,0,0,0-.77-.76H50.7a.76.76,0,0,1-.77-.77V31.47a.76.76,0,0,0-.77-.77h-8a.76.76,0,0,0-.77.77v7.84a.76.76,0,0,1-.77.77H31.73a.77.77,0,0,0-.77.76V48.9a.78.78,0,0,0,.77.77h7.84a.76.76,0,0,1,.77.76v7.85A.76.76,0,0,0,41.11,59Z"/></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<defs>
|
||||
<linearGradient id="sg" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#818cf8"/>
|
||||
<stop offset="100%" stop-color="#4f46e5"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M32 4 L56 18 Q60 20 60 25 L60 44 Q60 52 52 56 L36 62 Q32 64 28 62 L12 56 Q4 52 4 44 L4 25 Q4 20 8 18 Z" fill="url(#sg)"/>
|
||||
<path d="M32 8 L53 20 Q56 22 56 26 L56 43 Q56 50 49 53 L35 59 Q32 60 29 59 L15 53 Q8 50 8 43 L8 26 Q8 22 11 20 Z" fill="#4f46e5"/>
|
||||
<path d="M32 12 L50 22 Q52 24 52 27 L52 42 Q52 48 46 50 L34 56 Q32 57 30 56 L18 50 Q12 48 12 42 L12 27 Q12 24 14 22 Z" fill="#6366f1"/>
|
||||
<polyline points="14,36 24,36 27,28 30,44 33,24 36,40 39,32 42,36 50,36" fill="none" stroke="#ffffff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 838 B |
@ -47,8 +47,8 @@ import { Input } from '@/components/ui/input'
|
||||
import { Select } from '@/components/ui/select'
|
||||
|
||||
const searchQuery = ref('')
|
||||
const filterBy = ref(localStorage.getItem('gatus:filter-by') || (typeof window !== 'undefined' && window.config?.defaultFilterBy) || 'none')
|
||||
const sortBy = ref(localStorage.getItem('gatus:sort-by') || (typeof window !== 'undefined' && window.config?.defaultSortBy) || 'name')
|
||||
const filterBy = ref(localStorage.getItem('pandus:filter-by') || (typeof window !== 'undefined' && window.config?.defaultFilterBy) || 'none')
|
||||
const sortBy = ref(localStorage.getItem('pandus:sort-by') || (typeof window !== 'undefined' && window.config?.defaultSortBy) || 'name')
|
||||
|
||||
const filterOptions = [
|
||||
{ label: 'None', value: 'none' },
|
||||
@ -67,7 +67,7 @@ const emit = defineEmits(['search', 'update:showOnlyFailing', 'update:showRecent
|
||||
const handleFilterChange = (value, store = true) => {
|
||||
filterBy.value = value
|
||||
if (store)
|
||||
localStorage.setItem('gatus:filter-by', value)
|
||||
localStorage.setItem('pandus:filter-by', value)
|
||||
|
||||
// Reset all filter states first
|
||||
emit('update:showOnlyFailing', false)
|
||||
@ -84,7 +84,7 @@ const handleFilterChange = (value, store = true) => {
|
||||
const handleSortChange = (value, store = true) => {
|
||||
sortBy.value = value
|
||||
if (store)
|
||||
localStorage.setItem('gatus:sort-by', value)
|
||||
localStorage.setItem('pandus:sort-by', value)
|
||||
|
||||
emit('update:sortBy', value)
|
||||
emit('update:groupByGroup', value === 'group')
|
||||
|
||||
@ -72,7 +72,7 @@ const DEFAULT_REFRESH_INTERVAL = '300'
|
||||
const THEME_COOKIE_NAME = 'theme'
|
||||
const THEME_COOKIE_MAX_AGE = 31536000 // 1 year
|
||||
const STORAGE_KEYS = {
|
||||
REFRESH_INTERVAL: 'gatus:refresh-interval'
|
||||
REFRESH_INTERVAL: 'pandus:refresh-interval'
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div id="social">
|
||||
<a href="https://github.com/TwiN/gatus" target="_blank" title="Gatus on GitHub">
|
||||
<a href="https://github.com/TwiN/gatus" target="_blank" title="Based on Gatus">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 16 16" class="hover:scale-110">
|
||||
<path fill="gray" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
|
||||
</svg>
|
||||
|
||||
@ -4,48 +4,48 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--background: 240 20% 99%;
|
||||
--foreground: 240 10% 6%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--card-foreground: 240 10% 6%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--popover-foreground: 240 10% 6%;
|
||||
--primary: 239 84% 67%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 240 20% 95%;
|
||||
--secondary-foreground: 240 10% 6%;
|
||||
--muted: 240 20% 95%;
|
||||
--muted-foreground: 240 5% 46%;
|
||||
--accent: 240 20% 95%;
|
||||
--accent-foreground: 240 10% 6%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--border: 240 12% 91%;
|
||||
--input: 240 12% 91%;
|
||||
--ring: 239 84% 67%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--background: 240 17% 8%;
|
||||
--foreground: 240 20% 95%;
|
||||
--card: 240 17% 10%;
|
||||
--card-foreground: 240 20% 95%;
|
||||
--popover: 240 17% 10%;
|
||||
--popover-foreground: 240 20% 95%;
|
||||
--primary: 239 84% 67%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 240 15% 18%;
|
||||
--secondary-foreground: 240 20% 95%;
|
||||
--muted: 240 15% 18%;
|
||||
--muted-foreground: 240 10% 60%;
|
||||
--accent: 240 15% 18%;
|
||||
--accent-foreground: 240 20% 95%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
--destructive-foreground: 240 20% 95%;
|
||||
--border: 240 15% 18%;
|
||||
--input: 240 15% 18%;
|
||||
--ring: 239 84% 67%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -224,7 +224,7 @@ const events = ref([])
|
||||
const currentPage = ref(1)
|
||||
const resultPageSize = 50
|
||||
const showResponseTimeChartAndBadges = ref(false)
|
||||
const showAverageResponseTime = ref(localStorage.getItem('gatus:show-average-response-time') !== 'false')
|
||||
const showAverageResponseTime = ref(localStorage.getItem('pandus:show-average-response-time') !== 'false')
|
||||
const selectedChartDuration = ref('24h')
|
||||
const isRefreshing = ref(false)
|
||||
|
||||
@ -247,7 +247,7 @@ const hostname = computed(() => {
|
||||
|
||||
const toggleShowAverageResponseTime = () => {
|
||||
showAverageResponseTime.value = !showAverageResponseTime.value
|
||||
localStorage.setItem('gatus:show-average-response-time', showAverageResponseTime.value ? 'true' : 'false')
|
||||
localStorage.setItem('pandus:show-average-response-time', showAverageResponseTime.value ? 'true' : 'false')
|
||||
}
|
||||
|
||||
const pageAverageResponseTime = computed(() => {
|
||||
|
||||
@ -219,9 +219,9 @@ const itemsPerPage = 96
|
||||
const searchQuery = ref('')
|
||||
const showOnlyFailing = ref(false)
|
||||
const showRecentFailures = ref(false)
|
||||
const showAverageResponseTime = ref(localStorage.getItem('gatus:show-average-response-time') !== 'false')
|
||||
const showAverageResponseTime = ref(localStorage.getItem('pandus:show-average-response-time') !== 'false')
|
||||
const groupByGroup = ref(false)
|
||||
const sortBy = ref(localStorage.getItem('gatus:sort-by') || 'name')
|
||||
const sortBy = ref(localStorage.getItem('pandus:sort-by') || 'name')
|
||||
const uncollapsedGroups = ref(new Set())
|
||||
const resultPageSize = 50
|
||||
|
||||
@ -483,7 +483,7 @@ const goToPage = (page) => {
|
||||
|
||||
const toggleShowAverageResponseTime = () => {
|
||||
showAverageResponseTime.value = !showAverageResponseTime.value
|
||||
localStorage.setItem('gatus:show-average-response-time', showAverageResponseTime.value ? 'true' : 'false')
|
||||
localStorage.setItem('pandus:show-average-response-time', showAverageResponseTime.value ? 'true' : 'false')
|
||||
}
|
||||
|
||||
const showTooltip = (result, event, action = 'hover') => {
|
||||
@ -513,21 +513,21 @@ const toggleGroupCollapse = (groupName) => {
|
||||
}
|
||||
// Save to localStorage
|
||||
const uncollapsed = Array.from(uncollapsedGroups.value)
|
||||
localStorage.setItem('gatus:uncollapsed-groups', JSON.stringify(uncollapsed))
|
||||
localStorage.removeItem('gatus:collapsed-groups') // Remove old key if it exists
|
||||
localStorage.setItem('pandus:uncollapsed-groups', JSON.stringify(uncollapsed))
|
||||
localStorage.removeItem('pandus:collapsed-groups') // Remove old key if it exists
|
||||
}
|
||||
|
||||
const initializeCollapsedGroups = () => {
|
||||
// Get saved uncollapsed groups from localStorage
|
||||
try {
|
||||
const saved = localStorage.getItem('gatus:uncollapsed-groups')
|
||||
const saved = localStorage.getItem('pandus:uncollapsed-groups')
|
||||
if (saved) {
|
||||
uncollapsedGroups.value = new Set(JSON.parse(saved))
|
||||
}
|
||||
// If no saved state, uncollapsedGroups stays empty (all collapsed by default)
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse saved uncollapsed groups:', e)
|
||||
localStorage.removeItem('gatus:uncollapsed-groups')
|
||||
localStorage.removeItem('pandus:uncollapsed-groups')
|
||||
// On error, uncollapsedGroups stays empty (all collapsed by default)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user