Updated MaintenanceAlert layout for better responsiveness
parent
ed04b8fead
commit
387220ab6c
|
|
@ -1,4 +1,4 @@
|
||||||
import { Alert, List, Text } from '@mantine/core'
|
import { Alert, List, Text, Group, Box } from '@mantine/core'
|
||||||
import { IconAlertTriangle } from '@tabler/icons-react'
|
import { IconAlertTriangle } from '@tabler/icons-react'
|
||||||
import { MaintenanceConfig, MonitorTarget } from '@/types/config'
|
import { MaintenanceConfig, MonitorTarget } from '@/types/config'
|
||||||
|
|
||||||
|
|
@ -21,18 +21,41 @@ export default function MaintenanceAlert({
|
||||||
}
|
}
|
||||||
color={upcoming ? 'gray' : maintenance.color || '#f29030'}
|
color={upcoming ? 'gray' : maintenance.color || '#f29030'}
|
||||||
withCloseButton={false}
|
withCloseButton={false}
|
||||||
style={{ position: 'relative', margin: '16px auto 0 auto', ...style }}
|
style={{ margin: '16px auto', ...style }}
|
||||||
>
|
>
|
||||||
{/* Date range in top right */}
|
{/* Body and dates in a responsive flex layout */}
|
||||||
<div
|
<Group
|
||||||
|
align="flex-start"
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
flexWrap: 'wrap',
|
||||||
top: 10,
|
justifyContent: 'space-between',
|
||||||
right: 10,
|
gap: 16,
|
||||||
|
[`@media (max-width: 600px)`]: { gap: 8 },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Maintenance description and affected components */}
|
||||||
|
<Box style={{ flex: '1 1 300px', minWidth: 200 }}>
|
||||||
|
<Text style={{ whiteSpace: 'pre-line' }}>{maintenance.body}</Text>
|
||||||
|
|
||||||
|
{maintenance.monitors && maintenance.monitors.length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text mt="xs"><b>Affected components:</b></Text>
|
||||||
|
<List size="sm" withPadding>
|
||||||
|
{maintenance.monitors.map((comp, idx) => (
|
||||||
|
<List.Item key={idx}>{comp.name}</List.Item>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Date range */}
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
flex: '0 0 auto',
|
||||||
fontSize: '0.85rem',
|
fontSize: '0.85rem',
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
padding: '2px 8px',
|
minWidth: 120,
|
||||||
borderRadius: 6,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{upcoming ? (
|
{upcoming ? (
|
||||||
|
|
@ -40,34 +63,22 @@ export default function MaintenanceAlert({
|
||||||
<b>Scheduled for:</b> {new Date(maintenance.start).toLocaleString()}
|
<b>Scheduled for:</b> {new Date(maintenance.start).toLocaleString()}
|
||||||
<br />
|
<br />
|
||||||
<b>Expected end:</b>{' '}
|
<b>Expected end:</b>{' '}
|
||||||
{maintenance.end ? new Date(maintenance.end).toLocaleString() : 'Until further notice'}
|
{maintenance.end
|
||||||
|
? new Date(maintenance.end).toLocaleString()
|
||||||
|
: 'Until further notice'}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<b>From:</b> {new Date(maintenance.start).toLocaleString()}
|
<b>From:</b> {new Date(maintenance.start).toLocaleString()}
|
||||||
<br />
|
<br />
|
||||||
<b>To:</b>{' '}
|
<b>To:</b>{' '}
|
||||||
{maintenance.end ? new Date(maintenance.end).toLocaleString() : 'Until further notice'}
|
{maintenance.end
|
||||||
</>
|
? new Date(maintenance.end).toLocaleString()
|
||||||
)}
|
: 'Until further notice'}
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Maintenance description */}
|
|
||||||
<Text style={{ whiteSpace: 'pre-line' }}>{maintenance.body}</Text>
|
|
||||||
|
|
||||||
{/* Affected components */}
|
|
||||||
{maintenance.monitors && maintenance.monitors.length > 0 && (
|
|
||||||
<>
|
|
||||||
<Text mt="xs">
|
|
||||||
<b>Affected components:</b>
|
|
||||||
</Text>
|
|
||||||
<List size="sm" withPadding>
|
|
||||||
{maintenance.monitors.map((comp, compIdx) => (
|
|
||||||
<List.Item key={compIdx}>{comp.name}</List.Item>
|
|
||||||
))}
|
|
||||||
</List>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
</Alert>
|
</Alert>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
136
uptime.config.ts
136
uptime.config.ts
|
|
@ -1,96 +1,35 @@
|
||||||
import { MaintenanceConfig, PageConfig, WorkerConfig } from './types/config'
|
import { MaintenanceConfig, PageConfig, WorkerConfig } from './types/config'
|
||||||
|
|
||||||
const pageConfig: PageConfig = {
|
const pageConfig: PageConfig = {
|
||||||
// Title for your status page
|
title: "Sylphian's Uptime",
|
||||||
title: "lyc8503's Status Page",
|
|
||||||
// Links shown at the header of your status page, could set `highlight` to `true`
|
|
||||||
links: [
|
links: [
|
||||||
{ link: 'https://github.com/lyc8503', label: 'GitHub' },
|
{ link: 'https://github.com/Sylphian-Network/', label: 'GitHub' },
|
||||||
{ link: 'https://blog.lyc8503.net/', label: 'Blog' },
|
|
||||||
{ link: 'mailto:me@lyc8503.net', label: 'Email Me', highlight: true },
|
|
||||||
],
|
],
|
||||||
// [OPTIONAL] Group your monitors
|
|
||||||
// If not specified, all monitors will be shown in a single list
|
|
||||||
// If specified, monitors will be grouped and ordered, not-listed monitors will be invisble (but still monitored)
|
|
||||||
group: {
|
group: {
|
||||||
'🌐 Public (example group name)': ['foo_monitor', 'bar_monitor', 'more monitor ids...'],
|
'Website': ['monitor'],
|
||||||
'🔐 Private': ['test_tcp_monitor'],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const workerConfig: WorkerConfig = {
|
const workerConfig: WorkerConfig = {
|
||||||
// Write KV at most every 3 minutes unless the status changed
|
|
||||||
kvWriteCooldownMinutes: 3,
|
kvWriteCooldownMinutes: 3,
|
||||||
// Enable HTTP Basic auth for status page & API by uncommenting the line below, format `<USERNAME>:<PASSWORD>`
|
|
||||||
// passwordProtection: 'username:password',
|
|
||||||
// Define all your monitors here
|
|
||||||
monitors: [
|
monitors: [
|
||||||
// Example HTTP Monitor
|
|
||||||
{
|
{
|
||||||
// `id` should be unique, history will be kept if the `id` remains constant
|
id: 'monitor',
|
||||||
id: 'foo_monitor',
|
name: 'Sylphian.net',
|
||||||
// `name` is used at status page and callback message
|
method: 'GET',
|
||||||
name: 'My API Monitor',
|
target: 'https://sylphian.net',
|
||||||
// `method` should be a valid HTTP Method
|
statusPageLink: 'https://sylphian.net',
|
||||||
method: 'POST',
|
|
||||||
// `target` is a valid URL
|
|
||||||
target: 'https://example.com',
|
|
||||||
// [OPTIONAL] `tooltip` is ONLY used at status page to show a tooltip
|
|
||||||
tooltip: 'This is a tooltip for this monitor',
|
|
||||||
// [OPTIONAL] `statusPageLink` is ONLY used for clickable link at status page
|
|
||||||
statusPageLink: 'https://example.com',
|
|
||||||
// [OPTIONAL] `hideLatencyChart` will hide status page latency chart if set to true
|
|
||||||
hideLatencyChart: false,
|
hideLatencyChart: false,
|
||||||
// [OPTIONAL] `expectedCodes` is an array of acceptable HTTP response codes, if not specified, default to 2xx
|
|
||||||
expectedCodes: [200],
|
expectedCodes: [200],
|
||||||
// [OPTIONAL] `timeout` in millisecond, if not specified, default to 10000
|
|
||||||
timeout: 10000,
|
|
||||||
// [OPTIONAL] headers to be sent
|
|
||||||
headers: {
|
|
||||||
'User-Agent': 'Uptimeflare',
|
|
||||||
Authorization: 'Bearer YOUR_TOKEN_HERE',
|
|
||||||
},
|
|
||||||
// [OPTIONAL] body to be sent
|
|
||||||
body: 'Hello, world!',
|
|
||||||
// [OPTIONAL] if specified, the response must contains the keyword to be considered as operational.
|
|
||||||
responseKeyword: 'success',
|
|
||||||
// [OPTIONAL] if specified, the response must NOT contains the keyword to be considered as operational.
|
|
||||||
responseForbiddenKeyword: 'bad gateway',
|
|
||||||
// [OPTIONAL] if specified, will call the check proxy to check the monitor, mainly for geo-specific checks
|
|
||||||
// refer to docs https://github.com/lyc8503/UptimeFlare/wiki/Check-proxy-setup before setting this value
|
|
||||||
// currently supports `worker://` and `http(s)://` proxies
|
|
||||||
checkProxy: 'https://xxx.example.com OR worker://weur',
|
|
||||||
// [OPTIONAL] if true, the check will fallback to local if the specified proxy is down
|
|
||||||
checkProxyFallback: true,
|
|
||||||
},
|
|
||||||
// Example TCP Monitor
|
|
||||||
{
|
|
||||||
id: 'test_tcp_monitor',
|
|
||||||
name: 'Example TCP Monitor',
|
|
||||||
// `method` should be `TCP_PING` for tcp monitors
|
|
||||||
method: 'TCP_PING',
|
|
||||||
// `target` should be `host:port` for tcp monitors
|
|
||||||
target: '1.2.3.4:22',
|
|
||||||
tooltip: 'My production server SSH',
|
|
||||||
statusPageLink: 'https://example.com',
|
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
|
headers: {
|
||||||
|
'User-Agent': 'Sylphian-Uptimeflare',
|
||||||
},
|
},
|
||||||
|
responseKeyword: 'Community platform by XenForo',
|
||||||
|
responseForbiddenKeyword: 'bad gateway',
|
||||||
|
}
|
||||||
],
|
],
|
||||||
notification: {
|
notification: {
|
||||||
// [Optional] apprise API server URL
|
|
||||||
// if not specified, no notification will be sent
|
|
||||||
appriseApiServer: 'https://apprise.example.com/notify',
|
|
||||||
// [Optional] recipient URL for apprise, refer to https://github.com/caronc/apprise
|
|
||||||
// if not specified, no notification will be sent
|
|
||||||
recipientUrl: 'tgram://bottoken/ChatID',
|
|
||||||
// [Optional] timezone used in notification messages, default to "Etc/GMT"
|
|
||||||
timeZone: 'Asia/Shanghai',
|
|
||||||
// [Optional] grace period in minutes before sending a notification
|
|
||||||
// notification will be sent only if the monitor is down for N continuous checks after the initial failure
|
|
||||||
// if not specified, notification will be sent immediately
|
|
||||||
gracePeriod: 5,
|
|
||||||
// [Optional] disable notification for monitors with specified ids
|
|
||||||
skipNotificationIds: ['foo_monitor', 'bar_monitor'],
|
|
||||||
},
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
onStatusChange: async (
|
onStatusChange: async (
|
||||||
|
|
@ -119,28 +58,39 @@ const workerConfig: WorkerConfig = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can define multiple maintenances here
|
|
||||||
// During maintenance, an alert will be shown at status page
|
|
||||||
// Also, related downtime notifications will be skipped (if any)
|
|
||||||
// Of course, you can leave it empty if you don't need this feature
|
|
||||||
// const maintenances: MaintenanceConfig[] = []
|
|
||||||
const maintenances: MaintenanceConfig[] = [
|
const maintenances: MaintenanceConfig[] = [
|
||||||
{
|
{
|
||||||
// [Optional] Monitor IDs to be affected by this maintenance
|
monitors: ['monitor'],
|
||||||
monitors: ['foo_monitor', 'bar_monitor'],
|
title: 'Scheduled Maintenance',
|
||||||
// [Optional] default to "Scheduled Maintenance" if not specified
|
body: 'The server will be undergoing regular maintenance.',
|
||||||
title: 'Test Maintenance',
|
start: '2025-09-27T11:00:00.000Z',
|
||||||
// Description of the maintenance, will be shown at status page
|
end: '2025-09-27T12:00:00.000Z',
|
||||||
body: 'This is a test maintenance, server software upgrade',
|
color: 'yellow',
|
||||||
// Start time of the maintenance, in UNIX timestamp or ISO 8601 format
|
|
||||||
start: '2025-04-27T00:00:00+08:00',
|
|
||||||
// [Optional] end time of the maintenance, in UNIX timestamp or ISO 8601 format
|
|
||||||
// if not specified, the maintenance will be considered as on-going
|
|
||||||
end: '2025-04-30T00:00:00+08:00',
|
|
||||||
// [Optional] color of the maintenance alert at status page, default to "yellow"
|
|
||||||
color: 'blue',
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
monitors: ['monitor'],
|
||||||
|
title: 'Scheduled Maintenance',
|
||||||
|
body: 'The server will be undergoing regular maintenance.',
|
||||||
|
start: '2025-09-27T11:00:00.000Z',
|
||||||
|
end: '2025-09-27T12:00:00.000Z',
|
||||||
|
color: 'white',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monitors: ['monitor'],
|
||||||
|
title: 'Active Scheduled Maintenance',
|
||||||
|
body: 'The server will be undergoing regular maintenance.',
|
||||||
|
start: '2025-09-12T11:00:00.000Z',
|
||||||
|
end: '2025-09-27T12:00:00.000Z',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
monitors: ['monitor'],
|
||||||
|
title: 'Active Scheduled Maintenance',
|
||||||
|
body: 'The server will be undergoing regular maintenance.',
|
||||||
|
start: '2025-09-12T11:00:00.000Z',
|
||||||
|
end: '2025-09-27T12:00:00.000Z',
|
||||||
|
color: 'blue',
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
// Don't forget this, otherwise compilation fails.
|
|
||||||
export { pageConfig, workerConfig, maintenances }
|
export { pageConfig, workerConfig, maintenances }
|
||||||
Loading…
Reference in New Issue