prometheus/web/ui/react-app/src/pages/status/Status.tsx

160 lines
4.5 KiB
TypeScript
Raw Normal View History

import React, { Fragment, FC, useState, useEffect } from 'react';
2019-11-12 05:35:47 -08:00
import { Table } from 'reactstrap';
import { withStatusIndicator } from '../../components/withStatusIndicator';
import { useFetch } from '../../hooks/useFetch';
import { usePathPrefix } from '../../contexts/PathPrefixContext';
import { API_PATH } from '../../constants/constants';
2019-11-12 05:35:47 -08:00
interface StatusPageProps {
2020-02-03 06:14:25 -08:00
data: Record<string, string>;
title: string;
2019-11-12 05:35:47 -08:00
}
2019-11-02 08:53:32 -07:00
2020-02-03 06:14:25 -08:00
export const statusConfig: Record<
string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2020-02-03 06:14:25 -08:00
{ title?: string; customizeValue?: (v: any, key: string) => any; customRow?: boolean; skip?: boolean }
> = {
2019-11-02 08:53:32 -07:00
startTime: { title: 'Start time', customizeValue: (v: string) => new Date(v).toUTCString() },
CWD: { title: 'Working directory' },
reloadConfigSuccess: {
title: 'Configuration reload',
customizeValue: (v: boolean) => (v ? 'Successful' : 'Unsuccessful'),
},
lastConfigTime: { title: 'Last successful configuration reload' },
corruptionCount: { title: 'WAL corruptions' },
goroutineCount: { title: 'Goroutines' },
storageRetention: { title: 'Storage retention' },
activeAlertmanagers: {
customRow: true,
2019-11-12 05:35:47 -08:00
customizeValue: (alertMgrs: { url: string }[], key) => {
2019-11-02 08:53:32 -07:00
return (
2019-11-12 05:35:47 -08:00
<Fragment key={key}>
2019-11-02 08:53:32 -07:00
<tr>
<th>Endpoint</th>
</tr>
{alertMgrs.map(({ url }) => {
const { origin, pathname } = new URL(url);
return (
<tr key={url}>
<td>
<a href={url}>{origin}</a>
{pathname}
</td>
</tr>
);
})}
</Fragment>
);
},
},
droppedAlertmanagers: { skip: true },
};
2020-02-03 06:14:25 -08:00
export const StatusContent: FC<StatusPageProps> = ({ data, title }) => {
2019-11-12 05:35:47 -08:00
return (
<>
2020-02-03 06:14:25 -08:00
<h2>{title}</h2>
<Table className="h-auto" size="sm" bordered striped>
<tbody>
{Object.entries(data).map(([k, v]) => {
const { title = k, customizeValue = (val: string) => val, customRow, skip } = statusConfig[k] || {};
2020-02-03 06:14:25 -08:00
if (skip) {
return null;
}
if (customRow) {
return customizeValue(v, k);
}
return (
<tr key={k}>
<th className="capitalize-title" style={{ width: '35%' }}>
{title}
</th>
<td className="text-break">{customizeValue(v, title)}</td>
</tr>
);
})}
</tbody>
</Table>
</>
2019-11-12 05:35:47 -08:00
);
};
const StatusWithStatusIndicator = withStatusIndicator(StatusContent);
StatusContent.displayName = 'Status';
const StatusResult: FC<{ fetchPath: string; title: string }> = ({ fetchPath, title }) => {
const { response, isLoading, error } = useFetch(fetchPath);
return (
<StatusWithStatusIndicator
key={title}
data={response.data}
title={title}
isLoading={isLoading}
error={error}
componentTitle={title}
/>
);
};
interface StatusProps {
agentMode?: boolean | false;
setAnimateLogo?: (animateLogo: boolean) => void;
}
const Status: FC<StatusProps> = ({ agentMode, setAnimateLogo }) => {
/* _
* /' \
* | |
* \__/ */
const [inputText, setInputText] = useState('');
useEffect(() => {
const handleKeyPress = (event: KeyboardEvent) => {
const keyPressed = event.key.toUpperCase();
setInputText((prevInputText) => {
const newInputText = prevInputText.slice(-3) + String.fromCharCode(((keyPressed.charCodeAt(0) - 64) % 26) + 65);
return newInputText;
});
};
document.addEventListener('keypress', handleKeyPress);
return () => {
document.removeEventListener('keypress', handleKeyPress);
};
}, []);
useEffect(() => {
if (setAnimateLogo && inputText != '') {
setAnimateLogo(inputText.toUpperCase() === 'QSPN');
}
}, [inputText]);
/* _
* /' \
* | |
* \__/ */
const pathPrefix = usePathPrefix();
const path = `${pathPrefix}/${API_PATH}`;
2019-11-12 05:35:47 -08:00
return (
2020-02-03 06:14:25 -08:00
<>
{[
{ fetchPath: `${path}/status/runtimeinfo`, title: 'Runtime Information' },
{ fetchPath: `${path}/status/buildinfo`, title: 'Build Information' },
{ fetchPath: `${path}/alertmanagers`, title: 'Alertmanagers' },
].map(({ fetchPath, title }) => {
if (agentMode && title === 'Alertmanagers') {
return null;
}
return <StatusResult fetchPath={fetchPath} title={title} />;
2020-02-03 06:14:25 -08:00
})}
</>
2019-11-12 05:35:47 -08:00
);
2019-11-02 08:53:32 -07:00
};
export default Status;